changeset 419:f713fc55bf7b v7.0109

updated for version 7.0109
author vimboss
date Mon, 18 Jul 2005 21:58:11 +0000
parents 84825cc6f049
children b8cc11a2a3b1
files runtime/doc/eval.txt runtime/doc/options.txt runtime/doc/syntax.txt runtime/doc/todo.txt runtime/doc/version7.txt runtime/filetype.vim runtime/syntax/html.vim src/dosinst.c src/edit.c src/eval.c src/ex_cmds2.c src/ex_getln.c src/fold.c src/gui_gtk.c src/gui_gtk_x11.c src/gui_w32.c src/memline.c src/menu.c src/misc1.c src/ops.c src/option.c src/os_amiga.c src/os_qnx.c src/proto/misc2.pro src/structs.h src/syntax.c src/testdir/test51.in src/testdir/test58.in src/version.c src/version.h
diffstat 30 files changed, 178 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jul 07
+*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jul 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -3979,8 +3979,10 @@ synID({lnum}, {col}, {trans})				*synID(
 		{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.
+		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
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 7.0aa.  Last change: 2005 Jul 11
+*options.txt*	For Vim version 7.0aa.  Last change: 2005 Jul 18
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -5700,11 +5700,14 @@ A jump table for the options with a shor
 	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.
-	As a special case the name of a .spl file can be given as-is.  This is
-	mainly for testing purposes.  You must make sure the correct encoding
-	is used, Vim doesn't check it.
+	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'.
+	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|.
 
 						*'spellsuggest'* *'sps'*
@@ -6021,10 +6024,9 @@ A jump table for the options with a shor
 			{not in Vi}
 			{not available when compiled without the |+syntax|
 			feature}
-	Maximum column in which to search for syntax items.  With longer lines
-	some parts may not be highlighted and following text may not be
-	highlighted correctly (e.g., when the start or end of a region is not
-	recognized because it is beyond 'synmaxcol').
+	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.
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1,4 +1,4 @@
-*syntax.txt*	For Vim version 7.0aa.  Last change: 2005 Jul 05
+*syntax.txt*	For Vim version 7.0aa.  Last change: 2005 Jul 18
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -2516,17 +2516,17 @@ 5. Defining a syntax					*:syn-define* *
 
 Vim understands three types of syntax items:
 
-1. Keyword.
+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.
+2. Match
    This is a match with a single regexp pattern.
 
-3. Region.
+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.
@@ -2565,13 +2565,30 @@ 3. An item that starts in an earlier pos
 
 DEFINING CASE						*:syn-case* *E390*
 
-:sy[ntax] case [match|ignore]
+: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}]
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Jul 13
+*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Jul 18
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -30,9 +30,11 @@ be worked on, but only if you sponsor Vi
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-Use vim_strncpy() in more places.
+"at" and "it" text objects: recognize HTML/SGML/XML tag pairs <b>asdf</b>
 
-When going over 'synmaxcol' don't highlight anything, stop regions.
+":e *.foo" completion with file name starting with "+" should be escaped.
+
+VMS patch for term.c also in Vim 6.3 (Zoltan Arpadffy)
 
 Add extra list of file locations.  Can be used with:
     :ltag	      list of matching tags, like :tselect
@@ -93,6 +95,7 @@ Awaiting response:
 -   Win32: tearoff menu window should have a scrollbar when it's taller than
     the screen.
 
+mblen(NULL, 0) also in Vim 6.3?
 
 
 PLANNED FOR VERSION 7.0:
@@ -1242,6 +1245,8 @@ Help:
 
 
 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)
@@ -2081,12 +2086,6 @@ 7   When using a pseudo-tty Vim should b
 7   Support "-visual <type>" command line argument.
 
 
-VMS:
--   Improvement: rewrite term/TTY handling.
--   Improvement: create VMS GTK runtime libraries on OpenVMS 7.1-2 (today GTK
-    works just on 7.3).
-
-
 Autocommands:
 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
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -1,4 +1,4 @@
-*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Jul 12
+*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Jul 13
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -448,6 +448,8 @@ Pascal indent file. (Neil Carter)
 
 Many filetype plugins and others from Nikolai Weibull.
 
+Xquery syntax file. (Jean-Marc Vanel)
+
 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.
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1,7 +1,7 @@
 " Vim support file to detect file types
 "
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2005 Jul 04
+" Last Change:	2005 Jul 13
 
 " Listen very carefully, I will say this only once
 if exists("did_load_filetypes")
@@ -1812,6 +1812,9 @@ au BufNewFile,BufRead *.ts,*.ui			setf x
 " 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
 
--- a/runtime/syntax/html.vim
+++ b/runtime/syntax/html.vim
@@ -2,7 +2,7 @@
 " Language:	HTML
 " Maintainer:	Claudio Fleiner <claudio@fleiner.com>
 " URL:		http://www.fleiner.com/vim/syntax/html.vim
-" Last Change:  2005 Jul 05
+" Last Change:  2005 Jul 18
 
 " Please check :help html.vim for some comments and a description of the options
 
@@ -27,6 +27,8 @@ endif
 
 syn case ignore
 
+syn spell toplevel
+
 " mark illegal characters
 syn match htmlError "[<>&]"
 
@@ -35,8 +37,8 @@ syn match htmlError "[<>&]"
 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,@NoSpell
-syn region  htmlTag		   start=+<[^/]+   end=+>+ contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent,htmlCssDefinition,@htmlPreproc,@htmlArgCluster,@NoSpell
+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
@@ -116,7 +118,7 @@ syn match htmlPreProcAttrName contained 
 
 if !exists("html_no_rendering")
   " rendering
-  syn cluster htmlTop contains=htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,htmlLink,javaScript,@htmlPreproc
+  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
@@ -146,7 +148,7 @@ if !exists("html_no_rendering")
   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=htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,javaScript,@htmlPreproc
+  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
@@ -154,7 +156,7 @@ if !exists("html_no_rendering")
   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
+  syn region htmlTitle start="<title\>" end="</title>"me=e-8 contains=@Spell,htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,javaScript,@htmlPreproc
 endif
 
 syn keyword htmlTagName		contained noscript
--- a/src/dosinst.c
+++ b/src/dosinst.c
@@ -2080,7 +2080,7 @@ print_cmd_line_help(void)
     printf("    or $HOME directory\n");
 #ifdef WIN3264
     printf("-register-OLE");
-    printf("    Register gvim for OLE\n");
+    printf("    Ignored\n");
 #endif
     printf("\n");
 }
--- a/src/edit.c
+++ b/src/edit.c
@@ -1970,8 +1970,7 @@ ins_compl_add_infercase(str, len, fname,
     {
 	/* Infer case of completed part -- webb */
 	/* Use IObuff, str would change text in buffer! */
-	STRNCPY(IObuff, str, len);
-	IObuff[len] = NUL;
+	vim_strncpy(IObuff, str, len);
 
 	/* Rule 1: Were any chars converted to lower? */
 	for (idx = 0; idx < completion_length; ++idx)
@@ -2010,7 +2009,7 @@ ins_compl_add_infercase(str, len, fname,
 	}
 
 	/* Copy the original case of the part we typed */
-	STRNCPY(IObuff, original_text, completion_length);
+	vim_strncpy(IObuff, original_text, completion_length);
 
 	return ins_compl_add(IObuff, len, fname, dir, reuse);
     }
@@ -3053,17 +3052,17 @@ ins_compl_get_exp(ini, dir)
 			    tmp_ptr = find_word_end(tmp_ptr);
 			    if (tmp_ptr > ptr)
 			    {
-				if (*ptr != ')' && IObuff[len-1] != TAB)
+				if (*ptr != ')' && IObuff[len - 1] != TAB)
 				{
-				    if (IObuff[len-1] != ' ')
+				    if (IObuff[len - 1] != ' ')
 					IObuff[len++] = ' ';
 				    /* IObuf =~ "\k.* ", thus len >= 2 */
 				    if (p_js
-					&& (IObuff[len-2] == '.'
+					&& (IObuff[len - 2] == '.'
 					    || (vim_strchr(p_cpo, CPO_JOINSP)
 								       == NULL
-						&& (IObuff[len-2] == '?'
-						    || IObuff[len-2] == '!'))))
+						&& (IObuff[len - 2] == '?'
+						 || IObuff[len - 2] == '!'))))
 					IObuff[len++] = ' ';
 				}
 				/* copy as much as posible of the new word */
@@ -3741,8 +3740,7 @@ ins_complete(c)
 				      curr_match->number, completion_matches);
 		else
 		    sprintf((char *)IObuff, _("match %d"), curr_match->number);
-		STRNCPY(match_ref, IObuff, 30 );
-		match_ref[30] = '\0';
+		vim_strncpy(match_ref, IObuff, 30);
 		edit_submode_extra = match_ref;
 		edit_submode_highl = HLF_R;
 		if (dollar_vcol)
--- a/src/eval.c
+++ b/src/eval.c
@@ -6197,8 +6197,7 @@ dict_find(d, key, len)
     else
     {
 	/* Avoid a malloc/free by using buf[]. */
-	STRNCPY(buf, key, len);
-	buf[len] = NUL;
+	vim_strncpy(buf, key, len);
 	akey = buf;
     }
 
@@ -10681,10 +10680,7 @@ f_inputdialog(argvars, rettv)
 	message = get_tv_string_chk(&argvars[0]);
 	if (argvars[1].v_type != VAR_UNKNOWN
 	    && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL)
-	{
-	    STRNCPY(IObuff, defstr, IOSIZE);
-	    IObuff[IOSIZE - 1] = NUL;
-	}
+	    vim_strncpy(IObuff, defstr, IOSIZE - 1);
 	else
 	    IObuff[0] = NUL;
 	if (message != NULL && defstr != NULL
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -5511,16 +5511,14 @@ prt_open_resource(resource)
         switch (dsc_line.type)
         {
         case PRT_DSC_TITLE_TYPE:
-            STRNCPY(resource->title, dsc_line.string, dsc_line.len);
-            resource->title[dsc_line.len] = '\0';
+            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:
-            STRNCPY(resource->version, dsc_line.string, dsc_line.len);
-            resource->version[dsc_line.len] = '\0';
+            vim_strncpy(resource->version, dsc_line.string, dsc_line.len);
             seen_version = TRUE;
             if (seen_title)
                 seen_all = TRUE;
@@ -5862,8 +5860,7 @@ prt_build_cid_fontname(font, name, name_
     fontname = (char *)alloc(name_len + 1);
     if (fontname == NULL)
         return FALSE;
-    STRNCPY(fontname, name, name_len);
-    fontname[name_len] = '\0';
+    vim_strncpy((char_u *)fontname, name, name_len);
     prt_ps_mb_font.ps_fontname[font] = fontname;
 
     return TRUE;
@@ -5977,7 +5974,6 @@ mch_print_init(psettings, jobname, force
     double      bottom;
 #ifdef FEAT_MBYTE
     int         cmap;
-    int         pmcs_len;
     char_u	*p_encoding;
     struct prt_ps_encoding_S *p_mbenc;
     struct prt_ps_encoding_S *p_mbenc_first;
@@ -6035,7 +6031,7 @@ mch_print_init(psettings, jobname, force
     if (prt_out_mbyte)
     {
         /* Build CMap name - will be same for all multi-byte fonts used */
-        prt_cmap[0] = '\0';
+        prt_cmap[0] = NUL;
 
         prt_custom_cmap = prt_out_mbyte && p_mbchar == NULL;
 
@@ -6051,26 +6047,26 @@ mch_print_init(psettings, jobname, force
             /* Add charset name if not empty */
             if (p_mbchar->cmap_charset != NULL)
             {
-                STRCAT(prt_cmap, p_mbchar->cmap_charset);
+                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 */
-            pmcs_len = STRLEN(p_pmcs);
-            if (pmcs_len == 0)
+            if (*p_pmcs == NUL)
             {
                 EMSG(_("E674: printmbcharset cannot be empty with multi-byte encoding."));
                 return FALSE;
             }
-            STRNCPY(prt_cmap, p_pmcs, STRLEN(p_pmcs));
-            prt_cmap[pmcs_len] = '\0';
+            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)
+        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, "-");
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -3239,10 +3239,7 @@ ExpandOne(xp, str, orig, options, mode)
 	}
 	ss = alloc((unsigned)len + 1);
 	if (ss)
-	{
-	    STRNCPY(ss, xp->xp_files[0], len);
-	    ss[len] = NUL;
-	}
+	    vim_strncpy(ss, xp->xp_files[0], (size_t)len);
 	findex = -1;			    /* next p_wc gets first one */
     }
 
@@ -3749,8 +3746,7 @@ addstar(fname, len, context)
 	retval = alloc(len + 4);
 	if (retval != NULL)
 	{
-	    STRNCPY(retval, fname, len);
-	    retval[len] = NUL;
+	    vim_strncpy(retval, fname, len);
 
 	    /*
 	     * Don't add a star to ~, ~user, $var or `cmd`.
--- a/src/fold.c
+++ b/src/fold.c
@@ -1809,10 +1809,7 @@ foldAddMarker(lnum, marker, markerlen)
 	    return;
 	STRCPY(newline, line);
 	if (p == NULL)
-	{
-	    STRNCPY(newline + line_len, marker, markerlen);
-	    newline[line_len + markerlen] = NUL;
-	}
+	    vim_strncpy(newline + line_len, marker, markerlen);
 	else
 	{
 	    STRCPY(newline + line_len, cms);
--- a/src/gui_gtk.c
+++ b/src/gui_gtk.c
@@ -1476,8 +1476,7 @@ dlg_destroy(GtkWidget *dlg)
 	const char *text;
 
 	text = gtk_entry_get_text(GTK_ENTRY(dialog_textentry));
-	STRNCPY(dialog_textfield, text, IOSIZE);
-	dialog_textfield[IOSIZE - 1] = NUL;
+	vim_strncpy(dialog_textfield, (char_u *)text, IOSIZE - 1);
     }
 
     /* Destroy the dialog, will break the waiting loop. */
@@ -2340,8 +2339,7 @@ gui_mch_dialog(int	type,	    /* type of 
 	    text = (char_u *)gtk_entry_get_text(GTK_ENTRY(entry));
 	    text = CONVERT_FROM_UTF8(text);
 
-	    STRNCPY(textfield, text, IOSIZE);
-	    textfield[IOSIZE - 1] = NUL;
+	    vim_strncpy(textfield, text, IOSIZE - 1);
 
 	    CONVERT_FROM_UTF8_FREE(text);
 	}
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -2325,9 +2325,9 @@ sm_client_die(GnomeClient *client, gpoin
     /* Don't write messages to the GUI anymore */
     full_screen = FALSE;
 
-    STRNCPY(IObuff, _("Vim: Received \"die\" request from session manager\n"),
-	    IOSIZE);
-    IObuff[IOSIZE - 1] = NUL;
+    vim_strncpy(IObuff,
+		    _("Vim: Received \"die\" request from session manager\n"),
+	    IOSIZE - 1);
     preserve_exit();
 }
 
@@ -3527,9 +3527,9 @@ mainwin_destroy_cb(GtkObject *object, gp
 
     if (!exiting) /* only do anything if the destroy was unexpected */
     {
-	STRNCPY(IObuff, _("Vim: Main window unexpectedly destroyed\n"),
-		IOSIZE);
-	IObuff[IOSIZE - 1] = NUL;
+	vim_strncpy(IObuff,
+		(char_u *)_("Vim: Main window unexpectedly destroyed\n"),
+		IOSIZE - 1);
 	preserve_exit();
     }
 }
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -3592,8 +3592,7 @@ gui_mch_tearoff(
 	if (label == NULL)
 	    break;
 
-	STRNCPY(text, menu->name, nameLen);
-	text[nameLen] = NUL;
+	vim_strncpy(text, menu->name, nameLen);
 	text = vim_strchr(text, TAB);	    /* stop at TAB before actext */
 	if (text == NULL)
 	    text = label + nameLen;	    /* no actext, use whole name */
--- a/src/memline.c
+++ b/src/memline.c
@@ -698,8 +698,7 @@ set_b0_fname(b0p, buf)
 	/* Systems that cannot translate "~user" back into a path: copy the
 	 * file name unmodified.  Do use slashes instead of backslashes for
 	 * portability. */
-	STRNCPY(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE);
-	b0p->b0_fname[B0_FNAME_SIZE - 1] = NUL;
+	vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE - 1);
 # ifdef BACKSLASH_IN_FILENAME
 	forward_slash(b0p->b0_fname);
 # endif
@@ -721,10 +720,7 @@ set_b0_fname(b0p, buf)
 	    /* 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)
-	    {
-		STRNCPY(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE);
-		b0p->b0_fname[B0_FNAME_SIZE - 1] = NUL;
-	    }
+		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);
--- a/src/menu.c
+++ b/src/menu.c
@@ -1258,8 +1258,7 @@ set_context_in_menu_cmd(xp, cmd, arg, fo
 	    path_name = alloc((unsigned)(after_dot - arg));
 	    if (path_name == NULL)
 		return NULL;
-	    STRNCPY(path_name, arg, after_dot - arg - 1);
-	    path_name[after_dot - arg - 1] = NUL;
+	    vim_strncpy(path_name, arg, after_dot - arg - 1);
 	}
 	name = path_name;
 	while (name != NULL && *name)
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -976,8 +976,7 @@ open_line(dir, flags, old_indent)
 		lead_len = 0;
 	    else
 	    {
-		STRNCPY(leader, saved_line, lead_len);
-		leader[lead_len] = NUL;
+		vim_strncpy(leader, saved_line, lead_len);
 
 		/*
 		 * Replace leader with lead_repl, right or left adjusted
@@ -3345,8 +3344,7 @@ init_homedir()
 	p = vim_strchr(var + 1, '%');
 	if (p != NULL)
 	{
-	    STRNCPY(NameBuff, var + 1, p - (var + 1));
-	    NameBuff[p - (var + 1)] = NUL;
+	    vim_strncpy(NameBuff, var + 1, p - (var + 1));
 	    exp = mch_getenv(NameBuff);
 	    if (exp != NULL && *exp != NUL
 					&& STRLEN(exp) + STRLEN(p) < MAXPATHL)
--- a/src/ops.c
+++ b/src/ops.c
@@ -2532,8 +2532,7 @@ op_change(oap)
 	{
 	    if ((ins_text = alloc_check((unsigned)(ins_len + 1))) != NULL)
 	    {
-		STRNCPY(ins_text, firstline + bd.textcol, ins_len);
-		ins_text[ins_len] = NUL;
+		vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len);
 		for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
 								     linenr++)
 		{
--- a/src/option.c
+++ b/src/option.c
@@ -4318,8 +4318,7 @@ skip:
 
 	if (errmsg != NULL)
 	{
-	    STRNCPY(IObuff, _(errmsg), IOSIZE - 1);
-	    IObuff[IOSIZE - 1] = NUL;
+	    vim_strncpy(IObuff, (char_u *)_(errmsg), IOSIZE - 1);
 	    i = STRLEN(IObuff) + 2;
 	    if (i + (arg - startarg) < IOSIZE)
 	    {
@@ -9365,7 +9364,7 @@ option_value2string(opp, opt_flags)
 	else if ((char_u **)opp->var == &p_pt)
 	    str2specialbuf(p_pt, NameBuff, MAXPATHL);
 	else
-	    STRNCPY(NameBuff, varp, MAXPATHL);
+	    vim_strncpy(NameBuff, varp, MAXPATHL - 1);
     }
 }
 
--- a/src/os_amiga.c
+++ b/src/os_amiga.c
@@ -626,7 +626,7 @@ mch_get_host_name(s, len)
     char_u  *s;
     int	    len;
 {
-    STRNCPY(s, "Amiga", len);
+    vim_strncpy(s, "Amiga", len - 1);
 }
 
 /*
@@ -690,7 +690,7 @@ mch_FullName(fname, buf, len, force)
 		{
 		    if (i < len - 1 && (i == 0 || buf[i - 1] != ':'))
 			buf[i++] = '/';
-		    STRNCPY(buf + i, fname, len - i);
+		    vim_strncpy(buf + i, fname, len - i - 1);
 		}
 	    }
 	}
--- a/src/os_qnx.c
+++ b/src/os_qnx.c
@@ -148,8 +148,7 @@ clip_mch_set_selection( VimClipboard *cb
 #endif
 	    }
 
-	    STRNCPY( text_clip, str, len );
-	    text_clip[ len ] = NUL;
+	    vim_strncpy( text_clip, str, len );
 
 	    vim_clip[ 1 ] = NUL;
 
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -36,7 +36,7 @@ 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, int len));
+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));
--- a/src/structs.h
+++ b/src/structs.h
@@ -1067,6 +1067,11 @@ struct dictvar_S
     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 */
+
 
 /*
  * buffer: structure that holds information about one file
@@ -1429,6 +1434,7 @@ struct file_buffer
     hashtab_T	b_keywtab;		/* syntax keywords hash table */
     hashtab_T	b_keywtab_ic;		/* idem, ignore case */
     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 */
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -396,6 +396,7 @@ static char_u *syn_getcurline __ARGS((vo
 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));
@@ -1698,6 +1699,17 @@ get_syntax_attr(col, can_spell)
     if (syn_buf->b_sst_array == NULL)
 	return 0;
 
+    /* After 'synmaxcol' the attribute is always zero. */
+    if (syn_buf->b_p_smc > 0 && col >= 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();
@@ -2189,13 +2201,12 @@ syn_current_attr(syncing, displaying, ca
 	     * 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 = TRUE;
+		    *can_spell = (syn_buf->b_syn_spell != SYNSPL_NOTOP);
 		else
 		{
 		    sps.inc_tag = 0;
@@ -2207,9 +2218,11 @@ syn_current_attr(syncing, displaying, ca
 	    else
 	    {
 		/* The @Spell cluster is defined: Do spelling in items with
-		 * the @Spell cluster.  But not when @NoSpell is also there. */
+		 * 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 = FALSE;
+		    *can_spell = (syn_buf->b_syn_spell == SYNSPL_TOP);
 		else
 		{
 		    sps.inc_tag = 0;
@@ -2248,8 +2261,11 @@ syn_current_attr(syncing, displaying, ca
 	}
     }
     else if (can_spell != NULL)
-	/* Only do spelling when there is no @Spell cluster. */
-	*can_spell = (syn_buf->b_spell_cluster_id == 0);
+	/* 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
@@ -3050,8 +3066,7 @@ check_keyword_id(line, startcol, endcolp
      * Must make a copy of the keyword, so we can add a NUL and make it
      * lowercase.
      */
-    STRNCPY(keyword, kwp, kwlen);
-    keyword[kwlen] = NUL;
+    vim_strncpy(keyword, kwp, kwlen);
 
     /*
      * Try twice:
@@ -3120,6 +3135,33 @@ syn_cmd_case(eap, syncing)
 }
 
 /*
+ * 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", 4) == 0 && next - arg == 4)
+	curbuf->b_syn_spell = SYNSPL_DEFAULT;
+    else
+	EMSG2(_("E390: Illegal argument: %s"), arg);
+}
+
+/*
  * Clear all syntax info for one buffer.
  */
     void
@@ -3129,6 +3171,7 @@ syntax_clear(buf)
     int i;
 
     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 */
@@ -5519,8 +5562,7 @@ get_id_list(arg, keylen, list)
 		failed = TRUE;
 		break;
 	    }
-	    STRNCPY(name + 1, p, end - p);
-	    name[end - p + 1] = NUL;
+	    vim_strncpy(name + 1, p, end - p);
 	    if (       STRCMP(name + 1, "ALLBUT") == 0
 		    || STRCMP(name + 1, "ALL") == 0
 		    || STRCMP(name + 1, "TOP") == 0
@@ -5806,6 +5848,7 @@ static struct subcommand subcommands[] =
     {"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}
@@ -8131,8 +8174,7 @@ syn_name2id(name)
     /* 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! */
-    STRNCPY(name_u, name, 199);
-    name_u[199] = NUL;
+    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
--- a/src/testdir/test51.in
+++ b/src/testdir/test51.in
@@ -29,6 +29,8 @@ STARTTEST
 :%s/ctermbg=\d*/ctermbg=3/
 :" filter out possibly translated error message
 :%s/E475: [^:]*:/E475:/
+:" fix the fileformat
+:set ff&
 :wq!
 ENDTEST
 
--- a/src/testdir/test58.in
+++ b/src/testdir/test58.in
@@ -7,9 +7,9 @@ STARTTEST
 :set enc=latin1
 :e!
 :" First generate a .spl file from a .dic and a .aff file.
-gg:/^affstart1/+1,/^affend1/-1w Xtest.aff
-gg:/^dicstart/+1,/^dicend/-1w Xtest.dic
-:mkspell Xtest Xtest
+gg:/^affstart1/+1,/^affend1/-1w! Xtest.aff
+gg:/^dicstart/+1,/^dicend/-1w! Xtest.dic
+:mkspell! Xtest Xtest
 :"
 :" use that spell file
 :set spl=Xtest.latin1.spl
@@ -71,30 +71,29 @@ gg:/^affstart2/+1,/^affend2/-1w! Xtest.a
 :" also use an addition file
 gg:/^addstart/+1,/^addend/-1w! Xtest.latin1.add
 :mkspell! Xtest.latin1.add.spl Xtest.latin1.add
-:set spl=en
 :set spellfile=Xtest.latin1.add
 /^test2:
 ]s:let str = spellbadword()
 :$put =str
-:set spl=en_us
+:set spl=Xtest_us.latin1.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str
 `m]s:let str = spellbadword()
 :$put =str
-:set spl=en_gb
+:set spl=Xtest_gb.latin1.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str
 `m]s:let str = spellbadword()
 :$put =str
-:set spl=en_nz
+:set spl=Xtest_nz.latin1.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str
 `m]s:let str = spellbadword()
 :$put =str
-:set spl=en_ca
+:set spl=Xtest_ca.latin1.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str
--- a/src/version.c
+++ b/src/version.c
@@ -1159,11 +1159,9 @@ do_intro_line(row, mesg, add_version, at
 
     if (*mesg == ' ')
     {
-	STRNCPY(modby, _("Modified by "), MODBY_LEN);
-	modby[MODBY_LEN - 1] = NUL;
+	vim_strncpy(modby, _("Modified by "), MODBY_LEN - 1);
 	l = STRLEN(modby);
-	STRNCPY(modby + l, MODIFIED_BY, MODBY_LEN - l);
-	modby[MODBY_LEN - 1] = NUL;
+	vim_strncpy(modby + l, MODIFIED_BY, MODBY_LEN - l - 1);
 	mesg = modby;
     }
 #endif
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 12)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 12, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 18)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 18, compiled "