changeset 698:e402b0af6083

updated for version 7.0211
author vimboss
date Wed, 01 Mar 2006 22:01:55 +0000
parents f08390485cd3
children 2af8de31a3a8
files runtime/doc/message.txt runtime/doc/tabpage.txt runtime/plugin/matchparen.vim runtime/syntax/rd.vim runtime/syntax/sh.vim src/buffer.c src/ex_docmd.c src/macros.h src/message.c src/normal.c src/spell.c src/tag.c src/window.c
diffstat 13 files changed, 423 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/message.txt
+++ b/runtime/doc/message.txt
@@ -1,4 +1,4 @@
-*message.txt*   For Vim version 7.0aa.  Last change: 2006 Jan 08
+*message.txt*   For Vim version 7.0aa.  Last change: 2006 Mar 01
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -751,9 +751,12 @@ and the screen is about to be redrawn:
 -> 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', '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.
+-> 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
--- a/runtime/doc/tabpage.txt
+++ b/runtime/doc/tabpage.txt
@@ -1,4 +1,4 @@
-*tabpage.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 26
+*tabpage.txt*   For Vim version 7.0aa.  Last change: 2006 Mar 01
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -32,8 +32,9 @@ each tab page.  With the mouse you can c
 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|.  The commands that are aware of
-other tab pages than the current one are mentioned below.
+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
@@ -45,7 +46,7 @@ 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 10). |-p|
+tab page (up to 'tabpagemax'). |-p|
 
 A double click with the mouse in the tab pages line opens a new, empty tab
 page.  It is placed left of the position of the click.  The first click may
--- a/runtime/plugin/matchparen.vim
+++ b/runtime/plugin/matchparen.vim
@@ -1,6 +1,6 @@
 " Vim plugin for showing matching parens
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last Change: 2006 Feb 27
+" Last Change: 2006 Mar 01
 
 " Exit quickly when:
 " - this plugin was already loaded (or disabled)
@@ -28,7 +28,7 @@ endif
 function! s:Highlight_Matching_Pair()
   " Remove any previous match.
   if s:paren_hl_on
-    match none
+    3match none
     let s:paren_hl_on = 0
   endif
 
@@ -81,6 +81,8 @@ function! s:Highlight_Matching_Pair()
   if before > 0
     if &ve != ''
       let vcol = virtcol('.')
+      let old_ve = &ve
+      set ve=all
     endif
     call cursor(c_lnum, c_col - before)
   endif
@@ -88,6 +90,7 @@ function! s:Highlight_Matching_Pair()
   if before > 0
     if &ve != ''
       exe 'normal ' . vcol . '|'
+      let &ve = old_ve
     else
       call cursor(0, c_col)
     endif
@@ -95,12 +98,12 @@ function! s:Highlight_Matching_Pair()
 
   " If a match is found setup match highlighting.
   if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
-    exe 'match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
+    exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
 	  \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
     let s:paren_hl_on = 1
   endif
 endfunction
 
 " Define commands that will disable and enable the plugin.
-command! NoMatchParen match none | unlet! g:loaded_matchparen | au! matchparen
+command! NoMatchParen 3match none | unlet! g:loaded_matchparen | au! matchparen
 command! DoMatchParen runtime plugin/matchparen.vim | doau CursorMoved
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/rd.vim
@@ -0,0 +1,162 @@
+" Vim syntax file
+" Language:    R Help File
+" Maintainer:  Johannes Ranke <jranke@uni-bremen.de>
+" Last Change: 2006 Mär 01
+" Version:     0.5
+" 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.
+"              - I didn't yet include any special markup for S4 methods.
+"              - The two versions of \item{}{} markup are not 
+"                distinguished (in the \arguments{} environment, the items to
+"                be described are R identifiers, but not in the \describe{}
+"                environment).
+"              - There is no Latex markup in equations
+
+" 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 
+
+syn case match
+
+" Rd identifiers {{{
+syn region rdIdentifier matchgroup=rdSection	start="\\name{" end="}" 
+syn region rdIdentifier matchgroup=rdSection	start="\\alias{" end="}" 
+syn region rdIdentifier matchgroup=rdSection	start="\\pkg{" end="}" 
+syn region rdIdentifier matchgroup=rdSection	start="\\item{" end="}" contained
+syn region rdIdentifier matchgroup=rdSection start="\\method{" end=/}/ contained
+
+" Highlighting of R code using an existing r.vim syntax file if available {{{1
+let s:syntaxdir = expand("<sfile>:p:h") "look in the directory of this file
+let s:rsyntax = s:syntaxdir . "/r.vim"
+if filereadable(s:rsyntax)  
+  syn include @R <sfile>:p:h/r.vim
+elseif filereadable('/usr/share/vim/vim64/syntax/r.vim')  "and debian location
+  syn include @R /usr/share/vim/vimcurrent/syntax/r.vim
+else 
+  syn match rdRComment /\#.*/				"if no r.vim is found, do comments
+  syn cluster R contains=rdRComment 
+endif
+syn region rdRcode matchgroup=Delimiter start="\\examples{" matchgroup=Delimiter transparent end=/}/ contains=@R,rdSection
+syn region rdRcode matchgroup=Delimiter start="\\usage{" matchgroup=Delimiter transparent end=/}/ contains=@R,rdIdentifier
+syn region rdRcode matchgroup=Delimiter start="\\synopsis{" matchgroup=Delimiter transparent end=/}/ contains=@R
+syn region rdRcode matchgroup=Delimiter start="\\special{" matchgroup=Delimiter transparent end=/}/ contains=@R contained
+syn region rdRcode matchgroup=Delimiter start="\\code{" matchgroup=Delimiter transparent end=/}/ contains=@R contained
+
+" Strings {{{1
+syn region rdString start=/"/ end=/"/ 
+
+" Special TeX characters  ( \$ \& \% \# \{ \} \_) {{{1
+syn match rdSpecialChar        "\\[$&%#{}_]"
+
+" Special Delimiters {{{1
+syn match rdDelimiter		"\\cr"
+syn match rdDelimiter		"\\tab "
+
+" Keywords {{{1
+syn match rdKeyword	"\\R"
+syn match rdKeyword	"\\dots"
+syn match rdKeyword	"\\ldots"
+
+" Links {{{1
+syn region rdLink matchgroup=rdSection start="\\link{" end="}" contained keepend
+syn region rdLink matchgroup=rdSection start="\\link\[.*\]{" end="}" contained keepend
+
+" Type Styles {{{1
+syn match rdType		"\\emph\>"
+syn match rdType		"\\strong\>"
+syn match rdType		"\\bold\>"
+syn match rdType		"\\sQuote\>"
+syn match rdType		"\\dQuote\>"
+syn match rdType		"\\code\>"
+syn match rdType		"\\preformatted\>"
+syn match rdType		"\\kbd\>"
+syn match rdType		"\\samp\>"
+syn match rdType		"\\eqn\>"
+syn match rdType		"\\deqn\>"
+syn match rdType		"\\file\>"
+syn match rdType		"\\email\>"
+syn match rdType		"\\url\>"
+syn match rdType		"\\var\>"
+syn match rdType		"\\env\>"
+syn match rdType		"\\option\>"
+syn match rdType		"\\command\>"
+syn match rdType		"\\dfn\>"
+syn match rdType		"\\cite\>"
+syn match rdType		"\\acronym\>"
+
+" Rd sections {{{1
+syn match rdSection		"\\encoding\>"
+syn match rdSection		"\\title\>"
+syn match rdSection		"\\description\>"
+syn match rdSection		"\\concept\>"
+syn match rdSection		"\\arguments\>"
+syn match rdSection		"\\details\>"
+syn match rdSection		"\\value\>"
+syn match rdSection		"\\references\>"
+syn match rdSection		"\\note\>"
+syn match rdSection		"\\author\>"
+syn match rdSection		"\\seealso\>"
+syn match rdSection		"\\keyword\>"
+syn match rdSection		"\\docType\>"
+syn match rdSection		"\\format\>"
+syn match rdSection		"\\source\>"
+syn match rdSection     "\\itemize\>"
+syn match rdSection     "\\describe\>"
+syn match rdSection     "\\enumerate\>"
+syn match rdSection     "\\item "
+syn match rdSection     "\\item$"
+syn match rdSection		"\\tabular{[lcr]*}"
+syn match rdSection		"\\dontrun\>"
+syn match rdSection		"\\dontshow\>"
+syn match rdSection		"\\testonly\>"
+
+" Freely named Sections {{{1
+syn region rdFreesec matchgroup=Delimiter start="\\section{" matchgroup=Delimiter transparent end=/}/ 
+
+" Rd comments {{{1
+syn match rdComment /%.*$/ contained 
+
+" Error {{{1
+syn region rdRegion matchgroup=Delimiter start=/(/ matchgroup=Delimiter end=/)/ transparent contains=ALLBUT,rdError,rdBraceError,rdCurlyError
+syn region rdRegion matchgroup=Delimiter start=/{/ matchgroup=Delimiter end=/}/ transparent contains=ALLBUT,rdError,rdBraceError,rdParenError
+syn region rdRegion matchgroup=Delimiter start=/\[/ matchgroup=Delimiter end=/]/ transparent contains=ALLBUT,rdError,rdCurlyError,rdParenError
+syn match rdError      /[)\]}]/
+syn match rdBraceError /[)}]/ contained
+syn match rdCurlyError /[)\]]/ contained
+syn match rdParenError /[\]}]/ 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_rd_syntax_inits")
+  if version < 508
+    let did_rd_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink rdIdentifier  Identifier
+  HiLink rdString      String
+  HiLink rdKeyword     Keyword
+  HiLink rdLink        Underlined
+  HiLink rdType	       Type
+  HiLink rdSection     PreCondit
+  HiLink rdError       Error
+  HiLink rdBraceError  Error
+  HiLink rdCurlyError  Error
+  HiLink rdParenError  Error
+  HiLink rdDelimiter   Delimiter
+  HiLink rdComment     Comment
+  HiLink rdRComment    Comment
+  HiLink rdSpecialChar SpecialChar
+  delcommand HiLink
+endif 
+
+let   b:current_syntax = "rd"
+" vim: foldmethod=marker:
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -2,8 +2,8 @@
 " 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:		Feb 01, 2006
-" Version:		80
+" Last Change:		Mar 01, 2006
+" Version:		81
 " URL:		http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
 "
 " Using the following VIM variables: {{{1
@@ -123,7 +123,7 @@ 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
+syn match   shOption  "\s--[^ \t$`'"|]\+"ms=s+1
 
 " Operators: {{{1
 " ==========
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4191,6 +4191,8 @@ do_arg_all(count, forceit)
     int		p_ea_save;
     alist_T	*alist;		/* argument list to be used */
     buf_T	*buf;
+    tabpage_T	*tpnext;
+    int		had_tab = cmdmod.tab;
 
     if (ARGCOUNT <= 0)
     {
@@ -4214,79 +4216,97 @@ do_arg_all(count, forceit)
      * 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.
      */
-    for (wp = firstwin; wp != NULL; wp = wpnext)
+    if (had_tab > 0)
+	goto_tabpage_tp(first_tabpage);
+    for (;;)
     {
-	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
+	tpnext = curtab->tp_next;
+	for (wp = firstwin; wp != NULL; wp = wpnext)
 	{
-	    /* check if the buffer in this window is in the arglist */
-	    for (i = 0; i < ARGCOUNT; ++i)
+	    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
 	    {
-		if (ARGLIST[i].ae_fnum == buf->b_fnum
-			|| fullpathcmp(alist_name(&ARGLIST[i]),
-					      buf->b_ffname, TRUE) & FPC_SAME)
+		/* check if the buffer in this window is in the arglist */
+		for (i = 0; i < ARGCOUNT; ++i)
 		{
-		    if (i < opened_len)
-			opened[i] = TRUE;
-		    if (wp->w_alist != curwin->w_alist)
+		    if (ARGLIST[i].ae_fnum == buf->b_fnum
+			    || fullpathcmp(alist_name(&ARGLIST[i]),
+						  buf->b_ffname, TRUE) & FPC_SAME)
 		    {
-			/* 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;
+			if (i < opened_len)
+			    opened[i] = TRUE;
+			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;
 		    }
-		    break;
+		}
+	    }
+	    wp->w_arg_idx = i;
+
+	    if (i == ARGCOUNT)		/* 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
+		    if (firstwin == lastwin)	/* don't close last window */
+#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
 		}
 	    }
 	}
-	wp->w_arg_idx = i;
-
-	if (i == ARGCOUNT)		/* 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
-		if (firstwin == lastwin)	/* don't close last window */
-#endif
-		    use_firstwin = TRUE;
-#ifdef FEAT_WINDOWS
-		else
-		{
-		    win_close(wp, !P_HID(buf) && !bufIsChanged(buf));
+
+	/* 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 window */
-		    if (!win_valid(wpnext))
-			wpnext = firstwin;	/* start all over... */
+	/* check if autocommands removed the next tab page */
+	if (!valid_tabpage(tpnext))
+	    tpnext = first_tabpage;	/* start all over...*/
 # endif
-		}
-#endif
-	    }
-	}
+	goto_tabpage_tp(tpnext);
     }
 
     /*
@@ -4359,6 +4379,10 @@ do_arg_all(count, forceit)
 	    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. */
@@ -4390,6 +4414,10 @@ ex_buffer_all(eap)
     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;
@@ -4410,27 +4438,48 @@ ex_buffer_all(eap)
      * Close superfluous windows (two windows for the same buffer).
      * Also close windows that are not full-width.
      */
-    for (wp = firstwin; wp != NULL; wp = wpnext)
+#ifdef FEAT_WINDOWS
+    if (had_tab > 0)
+	goto_tabpage_tp(first_tabpage);
+    for (;;)
     {
-	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
-			  : wp->w_width != Columns)
-#endif
-		)
+#endif
+	tpnext = curtab->tp_next;
+	for (wp = firstwin; wp != NULL; wp = wpnext)
 	{
-	    win_close(wp, FALSE);
+	    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
+			: wp->w_width != Columns)
+#endif
+		    )
+	    {
+		win_close(wp, FALSE);
 #ifdef FEAT_AUTOCMD
-	    wpnext = firstwin;	/* just in case an autocommand does something
-				   strange with windows */
-	    open_wins = 0;
-#endif
+		wpnext = firstwin;	/* just in case an autocommand does
+					   something strange with windows */
+		open_wins = 0;
+#endif
+	    }
+	    else
+		++open_wins;
 	}
-	else
-	    ++open_wins;
+
+#ifdef FEAT_WINDOWS
+	/* 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);
     }
+#endif
 
     /*
      * Go through the buffer list.  When a buffer doesn't have a window yet,
@@ -4523,6 +4572,11 @@ ex_buffer_all(eap)
 	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;
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -4392,7 +4392,7 @@ repl_cmdline(eap, src, srclen, repl, cmd
      */
     len = (int)STRLEN(repl);
     i = (int)(src - *cmdlinep) + (int)STRLEN(src + srclen) + len + 3;
-    if (eap->nextcmd)
+    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! */
@@ -4411,7 +4411,7 @@ repl_cmdline(eap, src, srclen, repl, cmd
     STRCPY(new_cmdline + i, src + srclen);
     src = new_cmdline + i;		/* remember where to continue */
 
-    if (eap->nextcmd)			/* append next command */
+    if (eap->nextcmd != NULL)		/* append next command */
     {
 	i = (int)STRLEN(new_cmdline) + 1;
 	STRCPY(new_cmdline + i, eap->nextcmd);
@@ -10583,7 +10583,7 @@ ex_nohlsearch(eap)
 }
 
 /*
- * ":match {group} {pattern}"
+ * ":[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.
  */
@@ -10594,12 +10594,21 @@ ex_match(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.regprog);
-	curwin->w_match.regprog = NULL;
+	vim_free(curwin->w_match[mi].regprog);
+	curwin->w_match[mi].regprog = NULL;
 	redraw_later(NOT_VALID);	/* always need a redraw */
     }
 
@@ -10613,8 +10622,9 @@ ex_match(eap)
 	p = skiptowhite(eap->arg);
 	if (!eap->skip)
 	{
-	    curwin->w_match_id = syn_namen2id(eap->arg, (int)(p - eap->arg));
-	    if (curwin->w_match_id == 0)
+	    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;
@@ -10643,9 +10653,9 @@ ex_match(eap)
 
 	    c = *end;
 	    *end = NUL;
-	    curwin->w_match.regprog = vim_regcomp(p + 1, RE_MAGIC);
+	    curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
 	    *end = c;
-	    if (curwin->w_match.regprog == NULL)
+	    if (curwin->w_match[mi].regprog == NULL)
 	    {
 		EMSG2(_(e_invarg2), p);
 		return;
--- a/src/macros.h
+++ b/src/macros.h
@@ -30,12 +30,14 @@
 		       ? (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))
--- a/src/message.c
+++ b/src/message.c
@@ -932,22 +932,33 @@ wait_return(redraw)
 		c = K_IGNORE;
 	    }
 #endif
-	    if (p_more && !p_cp && (c == 'b' || c == 'k' || c == 'u'
-						    || c == 'g' || c == K_UP))
+	    /*
+	     * 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)
 	    {
-		/* scroll back to show older messages */
-		do_more_prompt(c);
-		if (quit_more)
+		if (c == 'b' || c == 'k' || c == 'u' || c == 'g' || c == K_UP)
 		{
-		    c = CAR;		/* just pretend CR was hit */
-		    quit_more = FALSE;
-		    got_int = FALSE;
+		    /* 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
-		{
+		else if (msg_scrolled > Rows - 2
+				     && (c == 'j' || c == K_DOWN || c == 'd'))
 		    c = K_IGNORE;
-		    hit_return_msg();
-		}
 	    }
 	} while ((had_got_int && c == Ctrl_C)
 				|| c == K_IGNORE
--- a/src/normal.c
+++ b/src/normal.c
@@ -4147,7 +4147,7 @@ find_decl(ptr, len, locally, thisblock, 
     curwin->w_cursor.col = 0;
 
     /* Search forward for the identifier, ignore comment lines. */
-    found_pos.lnum = 0;
+    clearpos(&found_pos);
     for (;;)
     {
 	t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
--- a/src/spell.c
+++ b/src/spell.c
@@ -172,6 +172,8 @@
  * 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
  *
@@ -241,6 +243,7 @@
  * <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
  *
  * <pflags>	1 byte	    bitmask of:
  *			    WFP_RARE	rare prefix
@@ -328,6 +331,7 @@ typedef long idx_T;
 /* 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 */
 
 /* only used for su_badflags */
 #define WF_MIXCAP   0x20	/* mix of upper and lower case: macaRONI */
@@ -461,6 +465,7 @@ struct slang_S
 				 * "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 */
@@ -528,6 +533,7 @@ typedef struct langp_S
 #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_END		255	/* end of sections */
 
 #define SNF_REQUIRED	1	/* <sectionflags>: required section */
@@ -602,6 +608,7 @@ typedef struct suggest_S
 
 /* 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 */
@@ -2010,7 +2017,7 @@ spell_move_to(wp, dir, allwords, curline
      * though...
      */
     lnum = wp->w_cursor.lnum;
-    found_pos.lnum = 0;
+    clearpos(&found_pos);
 
     while (!got_int)
     {
@@ -2663,6 +2670,10 @@ spell_load_file(fname, lang, old_lp, sil
 		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;
@@ -4554,6 +4565,7 @@ typedef struct afffile_S
     unsigned	af_bad;		/* BAD ID for banned word */
     unsigned	af_needaffix;	/* NEEDAFFIX ID */
     unsigned	af_needcomp;	/* NEEDCOMPOUND ID */
+    unsigned	af_nosuggest;	/* NOSUGGEST ID */
     int		af_pfxpostpone;	/* postpone prefixes without chop string */
     hashtab_T	af_pref;	/* hashtable for prefixes, affheader_T */
     hashtab_T	af_suff;	/* hashtable for suffixes, affheader_T */
@@ -4710,6 +4722,7 @@ typedef struct spellinfo_S
     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 */
@@ -5053,6 +5066,7 @@ spell_read_aff(spin, fname)
 			|| aff->af_bad != 0
 			|| aff->af_needaffix != 0
 			|| aff->af_needcomp != 0
+			|| aff->af_nosuggest != 0
 			|| compflags != NULL
 			|| aff->af_suff.ht_used > 0
 			|| aff->af_pref.ht_used > 0)
@@ -5064,10 +5078,6 @@ spell_read_aff(spin, fname)
 	    {
 		midword = getroom_save(spin, items[1]);
 	    }
-	    else if (STRCMP(items[0], "NOSPLITSUGS") == 0 && itemcnt == 1)
-	    {
-		/* ignored, we always split */
-	    }
 	    else if (STRCMP(items[0], "TRY") == 0 && itemcnt == 2)
 	    {
 		/* ignored, we look in the tree for what chars may appear */
@@ -5100,6 +5110,12 @@ spell_read_aff(spin, fname)
 		aff->af_needaffix = 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)
 	    {
@@ -5171,6 +5187,10 @@ spell_read_aff(spin, fname)
 	    {
 		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;
@@ -5223,8 +5243,9 @@ spell_read_aff(spin, fname)
 			    || 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_nosuggest
 			    || cur_aff->ah_flag == aff->af_needcomp)
-			smsg((char_u *)_("Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND in %s line %d: %s"),
+			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);
@@ -6242,6 +6263,9 @@ spell_read_dic(spin, fname, affile)
 	    if (affile->af_needcomp != 0 && flag_in_afflist(
 			   affile->af_flagtype, afflist, affile->af_needcomp))
 		flags |= WF_NEEDCOMP;
+	    if (affile->af_nosuggest != 0 && flag_in_afflist(
+			   affile->af_flagtype, afflist, affile->af_nosuggest))
+		flags |= WF_NOSUGGEST;
 
 	    if (affile->af_pfxpostpone)
 		/* Need to store the list of prefix IDs with the word. */
@@ -7671,6 +7695,16 @@ write_vim_spell(spin, fname)
 	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. */
@@ -10776,6 +10810,11 @@ suggest_trie_walk(su, lp, fword, soundfo
 	    ++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])
@@ -11127,7 +11166,11 @@ suggest_trie_walk(su, lp, fword, soundfo
 				&& !can_compound(slang, p,
 						compflags + sp->ts_compsplit))
 			    break;
-			newscore += SCORE_SPLIT;
+
+			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,
@@ -12670,6 +12713,10 @@ badword:
 	    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. */
--- a/src/tag.c
+++ b/src/tag.c
@@ -197,6 +197,9 @@ do_tag(tag, type, count, forceit, verbos
     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.
      */
--- a/src/window.c
+++ b/src/window.c
@@ -3087,9 +3087,9 @@ make_tabpages(maxcount)
     int		count = maxcount;
     int		todo;
 
-    /* Limit to 10 tabs. */
-    if (count > 10)
-	count = 10;
+    /* Limit to 'tabpagemax' tabs. */
+    if (count > p_tpm)
+	count = p_tpm;
 
 #ifdef FEAT_AUTOCMD
     /*
@@ -3852,7 +3852,9 @@ win_free(wp, tp)
 
     vim_free(wp->w_localdir);
 #ifdef FEAT_SEARCH_EXTRA
-    vim_free(wp->w_match.regprog);
+    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);