lkundrak / rpms / vim

Forked from rpms/vim 4 years ago
Clone
0e73038
To: vim-dev@vim.org
0e73038
Subject: patch 7.1.040
0e73038
Fcc: outbox
0e73038
From: Bram Moolenaar <Bram@moolenaar.net>
0e73038
Mime-Version: 1.0
0e73038
Content-Type: text/plain; charset=ISO-8859-1
0e73038
Content-Transfer-Encoding: 8bit
0e73038
------------
0e73038
0e73038
Patch 7.1.040
0e73038
Problem:    ":match" only supports three matches.
0e73038
Solution:   Add functions clearmatches(), getmatches(), matchadd(),
0e73038
	    matchdelete() and setmatches().  Changed the data structures for
0e73038
	    this.  A small bug in syntax.c is fixed, so newly created
0e73038
	    highlight groups can have their name resolved correctly from their
0e73038
	    ID.  (Martin Toft)
0e73038
Files:	    runtime/doc/eval.txt, runtime/doc/pattern.txt,
0e73038
	    runtime/doc/usr_41.txt, src/eval.c, src/ex_docmd.c,
0e73038
	    src/proto/window.pro, src/screen.c, src/structs.h, src/syntax.c,
0e73038
	    src/testdir/Makefile, src/testdir/test63.in,
0e73038
	    src/testdir/test63.ok, src/window.c
0e73038
0e73038
0e73038
*** ../vim-7.1.039/runtime/doc/eval.txt	Tue Jul 17 16:31:15 2007
0e73038
--- runtime/doc/eval.txt	Wed Jul 25 21:05:56 2007
0e73038
***************
0e73038
*** 1,4 ****
0e73038
! *eval.txt*      For Vim version 7.1.  Last change: 2007 Jul 11
0e73038
  
0e73038
  
0e73038
  		  VIM REFERENCE MANUAL    by Bram Moolenaar
0e73038
--- 1,4 ----
0e73038
! *eval.txt*      For Vim version 7.1.  Last change: 2007 Jul 25
0e73038
  
0e73038
  
0e73038
  		  VIM REFERENCE MANUAL    by Bram Moolenaar
0e73038
***************
0e73038
*** 1557,1562 ****
0e73038
--- 1557,1563 ----
0e73038
  changenr()			Number  current change number
0e73038
  char2nr( {expr})		Number	ASCII value of first char in {expr}
0e73038
  cindent( {lnum})		Number	C indent for line {lnum}
0e73038
+ clearmatches()			None	clear all matches
0e73038
  col( {expr})			Number	column nr of cursor or mark
0e73038
  complete({startcol}, {matches})	String  set Insert mode completion
0e73038
  complete_add( {expr})		Number	add completion match
0e73038
***************
0e73038
*** 1622,1627 ****
0e73038
--- 1623,1629 ----
0e73038
  getline( {lnum})		String	line {lnum} of current buffer
0e73038
  getline( {lnum}, {end})		List	lines {lnum} to {end} of current buffer
0e73038
  getloclist({nr})		List	list of location list items
0e73038
+ getmatches()			List	list of current matches
0e73038
  getpos( {expr})			List	position of cursor, mark, etc.
0e73038
  getqflist()			List	list of quickfix items
0e73038
  getreg( [{regname} [, 1]])	String	contents of register
0e73038
***************
0e73038
*** 1676,1682 ****
0e73038
--- 1678,1687 ----
0e73038
  				String	check for mappings matching {name}
0e73038
  match( {expr}, {pat}[, {start}[, {count}]])
0e73038
  				Number	position where {pat} matches in {expr}
0e73038
+ matchadd( {group}, {pattern}[, {priority}[, {id}]])
0e73038
+ 				Number	highlight {pattern} with {group}
0e73038
  matcharg( {nr})			List	arguments of |:match|
0e73038
+ matchdelete( {id})		Number	delete match identified by {id}
0e73038
  matchend( {expr}, {pat}[, {start}[, {count}]])
0e73038
  				Number	position where {pat} ends in {expr}
0e73038
  matchlist( {expr}, {pat}[, {start}[, {count}]])
0e73038
***************
0e73038
*** 1731,1736 ****
0e73038
--- 1736,1742 ----
0e73038
  setline( {lnum}, {line})	Number	set line {lnum} to {line}
0e73038
  setloclist( {nr}, {list}[, {action}])
0e73038
  				Number	modify location list using {list}
0e73038
+ setmatches( {list})		Number	restore a list of matches
0e73038
  setpos( {expr}, {list})		none	set the {expr} position to {list}
0e73038
  setqflist( {list}[, {action}])	Number	modify quickfix list using {list}
0e73038
  setreg( {n}, {v}[, {opt}])	Number	set register to value and type
0e73038
***************
0e73038
*** 2012,2017 ****
0e73038
--- 2018,2027 ----
0e73038
  		feature, -1 is returned.
0e73038
  		See |C-indenting|.
0e73038
  
0e73038
+ clearmatches()						*clearmatches()*
0e73038
+ 		Clears all matches previously defined by |matchadd()| and the
0e73038
+ 		|:match| commands.
0e73038
+ 
0e73038
  							*col()*
0e73038
  col({expr})	The result is a Number, which is the byte index of the column
0e73038
  		position given with {expr}.  The accepted positions are:
0e73038
***************
0e73038
*** 2918,2923 ****
0e73038
--- 2928,2955 ----
0e73038
  		returned.  For an invalid window number {nr}, an empty list is
0e73038
  		returned. Otherwise, same as getqflist().
0e73038
  
0e73038
+ getmatches()						*getmatches()*
0e73038
+ 		Returns a |List| with all matches previously defined by
0e73038
+ 		|matchadd()| and the |:match| commands.  |getmatches()| is
0e73038
+ 		useful in combination with |setmatches()|, as |setmatches()|
0e73038
+ 		can restore a list of matches saved by |getmatches()|.
0e73038
+ 		Example: >
0e73038
+ 			:echo getmatches()
0e73038
+ <			[{'group': 'MyGroup1', 'pattern': 'TODO',
0e73038
+ 			'priority': 10, 'id': 1}, {'group': 'MyGroup2',
0e73038
+ 			'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
0e73038
+ 			:let m = getmatches()
0e73038
+ 			:call clearmatches()
0e73038
+ 			:echo getmatches()
0e73038
+ <			[] >
0e73038
+ 			:call setmatches(m)
0e73038
+ 			:echo getmatches()
0e73038
+ <			[{'group': 'MyGroup1', 'pattern': 'TODO',
0e73038
+ 			'priority': 10, 'id': 1}, {'group': 'MyGroup2',
0e73038
+ 			'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
0e73038
+ 			:unlet m
0e73038
+ <
0e73038
+ 
0e73038
  getqflist()						*getqflist()*
0e73038
  		Returns a list with all the current quickfix errors.  Each
0e73038
  		list item is a dictionary with these entries:
0e73038
***************
0e73038
*** 3622,3627 ****
0e73038
--- 3654,3697 ----
0e73038
  		the pattern.  'smartcase' is NOT used.  The matching is always
0e73038
  		done like 'magic' is set and 'cpoptions' is empty.
0e73038
  
0e73038
+ 					*matchadd()* *E798* *E799* *E801*
0e73038
+ matchadd({group}, {pattern}[, {priority}[, {id}]])
0e73038
+ 		Defines a pattern to be highlighted in the current window (a
0e73038
+ 		"match").  It will be highlighted with {group}.  Returns an
0e73038
+ 		identification number (ID), which can be used to delete the
0e73038
+ 		match using |matchdelete()|.
0e73038
+ 
0e73038
+ 		The optional {priority} argument assigns a priority to the
0e73038
+ 		match.  A match with a high priority will have its
0e73038
+ 		highlighting overrule that of a match with a lower priority.
0e73038
+ 		A priority is specified as an integer (negative numbers are no
0e73038
+ 		exception).  If the {priority} argument is not specified, the
0e73038
+ 		default priority is 10.  The priority of 'hlsearch' is zero,
0e73038
+ 		hence all matches with a priority greater than zero will
0e73038
+ 		overrule it.  Syntax highlighting (see 'syntax') is a separate
0e73038
+ 		mechanism, and regardless of the chosen priority a match will
0e73038
+ 		always overrule syntax highlighting.
0e73038
+ 
0e73038
+ 		The optional {id} argument allows the request for a specific
0e73038
+ 		match ID.  If a specified ID is already taken, an error
0e73038
+ 		message will appear and the match will not be added.  An ID
0e73038
+ 		is specified as a positive integer (zero excluded).  IDs 1, 2
0e73038
+ 		and 3 are reserved for |:match|, |:2match| and |:3match|,
0e73038
+ 		respectively.  If the {id} argument is not specified,
0e73038
+ 		|matchadd()| automatically chooses a free ID.
0e73038
+ 
0e73038
+ 		The number of matches is not limited, as it is the case with
0e73038
+ 		the |:match| commands.
0e73038
+ 
0e73038
+ 		Example: >
0e73038
+ 			:highlight MyGroup ctermbg=green guibg=green
0e73038
+ 			:let m = matchadd("MyGroup", "TODO")
0e73038
+ <		Deletion of the pattern: >
0e73038
+ 			:call matchdelete(m)
0e73038
+ 
0e73038
+ <		A list of matches defined by |matchadd()| and |:match| are
0e73038
+ 		available from |getmatches()|.  All matches can be deleted in
0e73038
+ 		one operation by |clearmatches()|.
0e73038
  
0e73038
  matcharg({nr})							*matcharg()*
0e73038
  		Selects the {nr} match item, as set with a |:match|,
0e73038
***************
0e73038
*** 3631,3638 ****
0e73038
  			The pattern used.
0e73038
  		When {nr} is not 1, 2 or 3 returns an empty |List|.
0e73038
  		When there is no match item set returns ['', ''].
0e73038
! 		This is usef to save and restore a |:match|.
0e73038
! 
0e73038
  
0e73038
  matchend({expr}, {pat}[, {start}[, {count}]])			*matchend()*
0e73038
  		Same as match(), but return the index of first character after
0e73038
--- 3701,3715 ----
0e73038
  			The pattern used.
0e73038
  		When {nr} is not 1, 2 or 3 returns an empty |List|.
0e73038
  		When there is no match item set returns ['', ''].
0e73038
! 		This is useful to save and restore a |:match|.
0e73038
! 		Highlighting matches using the |:match| commands are limited
0e73038
! 		to three matches. |matchadd()| does not have this limitation.
0e73038
! 
0e73038
! matchdelete({id})			       *matchdelete()* *E802* *E803*
0e73038
! 		Deletes a match with ID {id} previously defined by |matchadd()|
0e73038
! 		or one of the |:match| commands.  Returns 0 if succesfull,
0e73038
! 		otherwise -1.  See example for |matchadd()|.  All matches can
0e73038
! 		be deleted in one operation by |clearmatches()|.
0e73038
  
0e73038
  matchend({expr}, {pat}[, {start}[, {count}]])			*matchend()*
0e73038
  		Same as match(), but return the index of first character after
0e73038
***************
0e73038
*** 4385,4391 ****
0e73038
  		When {nr} is zero the current window is used. For a location
0e73038
  		list window, the displayed location list is modified.  For an
0e73038
  		invalid window number {nr}, -1 is returned.
0e73038
! 		Otherwise, same as setqflist().
0e73038
  
0e73038
  							*setpos()*
0e73038
  setpos({expr}, {list})
0e73038
--- 4462,4474 ----
0e73038
  		When {nr} is zero the current window is used. For a location
0e73038
  		list window, the displayed location list is modified.  For an
0e73038
  		invalid window number {nr}, -1 is returned.
0e73038
! 		Otherwise, same as |setqflist()|.
0e73038
! 		Also see |location-list|.
0e73038
! 
0e73038
! setmatches({list})					*setmatches()*
0e73038
! 		Restores a list of matches saved by |getmatches()|.  Returns 0
0e73038
! 		if succesfull, otherwise -1.  All current matches are cleared
0e73038
! 		before the list is restored.  See example for |getmatches()|.
0e73038
  
0e73038
  							*setpos()*
0e73038
  setpos({expr}, {list})
0e73038
*** ../vim-7.1.039/runtime/doc/pattern.txt	Sat May 12 16:57:31 2007
0e73038
--- runtime/doc/pattern.txt	Tue Jul 24 15:47:01 2007
0e73038
***************
0e73038
*** 1212,1218 ****
0e73038
  		{group} must exist at the moment this command is executed.
0e73038
  
0e73038
  		The {group} highlighting still applies when a character is
0e73038
! 		to be highlighted for 'hlsearch'.
0e73038
  
0e73038
  		Note that highlighting the last used search pattern with
0e73038
  		'hlsearch' is used in all windows, while the pattern defined
0e73038
--- 1212,1221 ----
0e73038
  		{group} must exist at the moment this command is executed.
0e73038
  
0e73038
  		The {group} highlighting still applies when a character is
0e73038
! 		to be highlighted for 'hlsearch', as the highlighting for
0e73038
! 		matches is given higher priority than that of 'hlsearch'.
0e73038
! 		Syntax highlighting (see 'syntax') is also overruled by
0e73038
! 		matches.
0e73038
  
0e73038
  		Note that highlighting the last used search pattern with
0e73038
  		'hlsearch' is used in all windows, while the pattern defined
0e73038
***************
0e73038
*** 1226,1233 ****
0e73038
  		display you may get unexpected results.  That is because Vim
0e73038
  		looks for a match in the line where redrawing starts.
0e73038
  
0e73038
! 		Also see |matcharg()|, it returns the highlight group and
0e73038
! 		pattern of a previous :match command.
0e73038
  
0e73038
  		Another example, which highlights all characters in virtual
0e73038
  		column 72 and more: >
0e73038
--- 1229,1243 ----
0e73038
  		display you may get unexpected results.  That is because Vim
0e73038
  		looks for a match in the line where redrawing starts.
0e73038
  
0e73038
! 		Also see |matcharg()|and |getmatches()|. The former returns
0e73038
! 		the highlight group and pattern of a previous |:match|
0e73038
! 		command.  The latter returns a list with highlight groups and
0e73038
! 		patterns defined by both |matchadd()| and |:match|.
0e73038
! 
0e73038
! 		Highlighting matches using |:match| are limited to three
0e73038
! 		matches (aside from |:match|, |:2match| and |:3match|are
0e73038
! 		available). |matchadd()| does not have this limitation and in
0e73038
! 		addition makes it possible to prioritize matches.
0e73038
  
0e73038
  		Another example, which highlights all characters in virtual
0e73038
  		column 72 and more: >
0e73038
*** ../vim-7.1.039/runtime/doc/usr_41.txt	Sat May 12 15:54:55 2007
0e73038
--- runtime/doc/usr_41.txt	Tue Jul 24 15:47:01 2007
0e73038
***************
0e73038
*** 763,775 ****
0e73038
--- 763,784 ----
0e73038
  	foldtextresult()	get the text displayed for a closed fold
0e73038
  
0e73038
  Syntax and highlighting:
0e73038
+ 	clearmatches()		clear all matches defined by |matchadd()| and
0e73038
+ 				the |:match| commands
0e73038
+ 	getmatches()		get all matches defined by |matchadd()| and
0e73038
+ 				the |:match| commands
0e73038
  	hlexists()		check if a highlight group exists
0e73038
  	hlID()			get ID of a highlight group
0e73038
  	synID()			get syntax ID at a specific position
0e73038
  	synIDattr()		get a specific attribute of a syntax ID
0e73038
  	synIDtrans()		get translated syntax ID
0e73038
  	diff_hlID()		get highlight ID for diff mode at a position
0e73038
+ 	matchadd()		define a pattern to highlight (a "match")
0e73038
  	matcharg()		get info about |:match| arguments
0e73038
+ 	matchdelete()		delete a match defined by |matchadd()| or a
0e73038
+ 				|:match| command
0e73038
+ 	setmatches()		restore a list of matches saved by
0e73038
+ 				|getmatches()|
0e73038
  
0e73038
  Spelling:
0e73038
  	spellbadword()		locate badly spelled word at or after cursor
0e73038
*** ../vim-7.1.039/src/eval.c	Tue Jul 24 14:32:44 2007
0e73038
--- src/eval.c	Tue Jul 24 20:40:52 2007
0e73038
***************
0e73038
*** 475,480 ****
0e73038
--- 475,481 ----
0e73038
  static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
+ static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  #if defined(FEAT_INS_EXPAND)
0e73038
  static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
***************
0e73038
*** 529,534 ****
0e73038
--- 530,536 ----
0e73038
  static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
+ static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
***************
0e73038
*** 577,583 ****
0e73038
--- 579,587 ----
0e73038
  static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
+ static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
+ static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
***************
0e73038
*** 618,623 ****
0e73038
--- 622,628 ----
0e73038
  static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
+ static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
  static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
0e73038
***************
0e73038
*** 7046,7051 ****
0e73038
--- 7051,7057 ----
0e73038
      {"changenr",	0, 0, f_changenr},
0e73038
      {"char2nr",		1, 1, f_char2nr},
0e73038
      {"cindent",		1, 1, f_cindent},
0e73038
+     {"clearmatches",	0, 0, f_clearmatches},
0e73038
      {"col",		1, 1, f_col},
0e73038
  #if defined(FEAT_INS_EXPAND)
0e73038
      {"complete",	2, 2, f_complete},
0e73038
***************
0e73038
*** 7102,7107 ****
0e73038
--- 7108,7114 ----
0e73038
      {"getftype",	1, 1, f_getftype},
0e73038
      {"getline",		1, 2, f_getline},
0e73038
      {"getloclist",	1, 1, f_getqflist},
0e73038
+     {"getmatches",  	0, 0, f_getmatches},
0e73038
      {"getpos",		1, 1, f_getpos},
0e73038
      {"getqflist",	0, 0, f_getqflist},
0e73038
      {"getreg",		0, 2, f_getreg},
0e73038
***************
0e73038
*** 7152,7158 ****
0e73038
--- 7159,7167 ----
0e73038
      {"maparg",		1, 3, f_maparg},
0e73038
      {"mapcheck",	1, 3, f_mapcheck},
0e73038
      {"match",		2, 4, f_match},
0e73038
+     {"matchadd",	2, 4, f_matchadd},
0e73038
      {"matcharg",	1, 1, f_matcharg},
0e73038
+     {"matchdelete",	1, 1, f_matchdelete},
0e73038
      {"matchend",	2, 4, f_matchend},
0e73038
      {"matchlist",	2, 4, f_matchlist},
0e73038
      {"matchstr",	2, 4, f_matchstr},
0e73038
***************
0e73038
*** 7193,7198 ****
0e73038
--- 7202,7208 ----
0e73038
      {"setcmdpos",	1, 1, f_setcmdpos},
0e73038
      {"setline",		2, 2, f_setline},
0e73038
      {"setloclist",	2, 3, f_setloclist},
0e73038
+     {"setmatches",	1, 1, f_setmatches},
0e73038
      {"setpos",		2, 2, f_setpos},
0e73038
      {"setqflist",	1, 2, f_setqflist},
0e73038
      {"setreg",		2, 3, f_setreg},
0e73038
***************
0e73038
*** 8243,8248 ****
0e73038
--- 8253,8272 ----
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
+  * "clearmatches()" function
0e73038
+  */
0e73038
+ /*ARGSUSED*/
0e73038
+     static void
0e73038
+ f_clearmatches(argvars, rettv)
0e73038
+     typval_T	*argvars;
0e73038
+     typval_T	*rettv;
0e73038
+ {
0e73038
+ #ifdef FEAT_SEARCH_EXTRA
0e73038
+     clear_matches(curwin);
0e73038
+ #endif
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
   * "col(string)" function
0e73038
   */
0e73038
      static void
0e73038
***************
0e73038
*** 10278,10283 ****
0e73038
--- 10302,10341 ----
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
+  * "getmatches()" function
0e73038
+  */
0e73038
+ /*ARGSUSED*/
0e73038
+     static void
0e73038
+ f_getmatches(argvars, rettv)
0e73038
+     typval_T	*argvars;
0e73038
+     typval_T	*rettv;
0e73038
+ {
0e73038
+ #ifdef FEAT_SEARCH_EXTRA
0e73038
+     dict_T	*dict;
0e73038
+     matchitem_T	*cur = curwin->w_match_head;
0e73038
+ 
0e73038
+     rettv->vval.v_number = 0;
0e73038
+ 
0e73038
+     if (rettv_list_alloc(rettv) == OK)
0e73038
+     {
0e73038
+ 	while (cur != NULL)
0e73038
+ 	{
0e73038
+ 	    dict = dict_alloc();
0e73038
+ 	    if (dict == NULL)
0e73038
+ 		return;
0e73038
+ 	    ++dict->dv_refcount;
0e73038
+ 	    dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
0e73038
+ 	    dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
0e73038
+ 	    dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
0e73038
+ 	    dict_add_nr_str(dict, "id", (long)cur->id, NULL);
0e73038
+ 	    list_append_dict(rettv->vval.v_list, dict);
0e73038
+ 	    cur = cur->next;
0e73038
+ 	}
0e73038
+     }
0e73038
+ #endif
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
   * "getpos(string)" function
0e73038
   */
0e73038
      static void
0e73038
***************
0e73038
*** 12448,12453 ****
0e73038
--- 12506,12547 ----
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
+  * "matchadd()" function
0e73038
+  */
0e73038
+     static void
0e73038
+ f_matchadd(argvars, rettv)
0e73038
+     typval_T	*argvars;
0e73038
+     typval_T	*rettv;
0e73038
+ {
0e73038
+ #ifdef FEAT_SEARCH_EXTRA
0e73038
+     char_u	buf[NUMBUFLEN];
0e73038
+     char_u	*grp = get_tv_string_buf_chk(&argvars[0], buf);	/* group */
0e73038
+     char_u	*pat = get_tv_string_buf_chk(&argvars[1], buf);	/* pattern */
0e73038
+     int		prio = 10;	/* default priority */
0e73038
+     int		id = -1;
0e73038
+     int		error = FALSE;
0e73038
+ 
0e73038
+     rettv->vval.v_number = -1;
0e73038
+ 
0e73038
+     if (grp == NULL || pat == NULL)
0e73038
+ 	return;
0e73038
+     if (argvars[2].v_type != VAR_UNKNOWN)
0e73038
+ 	prio = get_tv_number_chk(&argvars[2], &error);
0e73038
+     if (argvars[3].v_type != VAR_UNKNOWN)
0e73038
+ 	id = get_tv_number_chk(&argvars[3], &error);
0e73038
+     if (error == TRUE)
0e73038
+ 	return;
0e73038
+     if (id >= 1 && id <= 3)
0e73038
+     {
0e73038
+ 	EMSGN("E798: ID is reserved for \":match\": %ld", id);
0e73038
+ 	return;
0e73038
+     }
0e73038
+ 
0e73038
+     rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
0e73038
+ #endif
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
   * "matcharg()" function
0e73038
   */
0e73038
      static void
0e73038
***************
0e73038
*** 12458,12477 ****
0e73038
      if (rettv_list_alloc(rettv) == OK)
0e73038
      {
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
! 	int	mi = get_tv_number(&argvars[0]);
0e73038
  
0e73038
! 	if (mi >= 1 && mi <= 3)
0e73038
  	{
0e73038
! 	    list_append_string(rettv->vval.v_list,
0e73038
! 				 syn_id2name(curwin->w_match_id[mi - 1]), -1);
0e73038
! 	    list_append_string(rettv->vval.v_list,
0e73038
! 					     curwin->w_match_pat[mi - 1], -1);
0e73038
  	}
0e73038
  #endif
0e73038
      }
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
   * "matchend()" function
0e73038
   */
0e73038
      static void
0e73038
--- 12552,12593 ----
0e73038
      if (rettv_list_alloc(rettv) == OK)
0e73038
      {
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
! 	int	    id = get_tv_number(&argvars[0]);
0e73038
! 	matchitem_T *m;
0e73038
  
0e73038
! 	if (id >= 1 && id <= 3)
0e73038
  	{
0e73038
! 	    if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
0e73038
! 	    {
0e73038
! 		list_append_string(rettv->vval.v_list,
0e73038
! 						syn_id2name(m->hlg_id), -1);
0e73038
! 		list_append_string(rettv->vval.v_list, m->pattern, -1);
0e73038
! 	    }
0e73038
! 	    else
0e73038
! 	    {
0e73038
! 		list_append_string(rettv->vval.v_list, NUL, -1);
0e73038
! 		list_append_string(rettv->vval.v_list, NUL, -1);
0e73038
! 	    }
0e73038
  	}
0e73038
  #endif
0e73038
      }
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
+  * "matchdelete()" function
0e73038
+  */
0e73038
+     static void
0e73038
+ f_matchdelete(argvars, rettv)
0e73038
+     typval_T	*argvars;
0e73038
+     typval_T	*rettv;
0e73038
+ {
0e73038
+ #ifdef FEAT_SEARCH_EXTRA
0e73038
+     rettv->vval.v_number = match_delete(curwin,
0e73038
+ 				       (int)get_tv_number(&argvars[0]), TRUE);
0e73038
+ #endif
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
   * "matchend()" function
0e73038
   */
0e73038
      static void
0e73038
***************
0e73038
*** 14506,14511 ****
0e73038
--- 14622,14687 ----
0e73038
      win = find_win_by_nr(&argvars[0], NULL);
0e73038
      if (win != NULL)
0e73038
  	set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
+  * "setmatches()" function
0e73038
+  */
0e73038
+     static void
0e73038
+ f_setmatches(argvars, rettv)
0e73038
+     typval_T	*argvars;
0e73038
+     typval_T	*rettv;
0e73038
+ {
0e73038
+ #ifdef FEAT_SEARCH_EXTRA
0e73038
+     list_T	*l;
0e73038
+     listitem_T	*li;
0e73038
+     dict_T	*d;
0e73038
+ 
0e73038
+     rettv->vval.v_number = -1;
0e73038
+     if (argvars[0].v_type != VAR_LIST)
0e73038
+     {
0e73038
+ 	EMSG(_(e_listreq));
0e73038
+ 	return;
0e73038
+     }
0e73038
+     if ((l = argvars[0].vval.v_list) != NULL)
0e73038
+     {
0e73038
+ 
0e73038
+ 	/* To some extent make sure that we are dealing with a list from
0e73038
+ 	 * "getmatches()". */
0e73038
+ 	li = l->lv_first;
0e73038
+ 	while (li != NULL)
0e73038
+ 	{
0e73038
+ 	    if (li->li_tv.v_type != VAR_DICT
0e73038
+ 		    || (d = li->li_tv.vval.v_dict) == NULL)
0e73038
+ 	    {
0e73038
+ 		EMSG(_(e_invarg));
0e73038
+ 		return;
0e73038
+ 	    }
0e73038
+ 	    if (!(dict_find(d, (char_u *)"group", -1) != NULL
0e73038
+ 			&& dict_find(d, (char_u *)"pattern", -1) != NULL
0e73038
+ 			&& dict_find(d, (char_u *)"priority", -1) != NULL
0e73038
+ 			&& dict_find(d, (char_u *)"id", -1) != NULL))
0e73038
+ 	    {
0e73038
+ 		EMSG(_(e_invarg));
0e73038
+ 		return;
0e73038
+ 	    }
0e73038
+ 	    li = li->li_next;
0e73038
+ 	}
0e73038
+ 
0e73038
+ 	clear_matches(curwin);
0e73038
+ 	li = l->lv_first;
0e73038
+ 	while (li != NULL)
0e73038
+ 	{
0e73038
+ 	    d = li->li_tv.vval.v_dict;
0e73038
+ 	    match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
0e73038
+ 		    get_dict_string(d, (char_u *)"pattern", FALSE),
0e73038
+ 		    (int)get_dict_number(d, (char_u *)"priority"),
0e73038
+ 		    (int)get_dict_number(d, (char_u *)"id"));
0e73038
+ 	    li = li->li_next;
0e73038
+ 	}
0e73038
+ 	rettv->vval.v_number = 0;
0e73038
+     }
0e73038
+ #endif
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
*** ../vim-7.1.039/src/ex_docmd.c	Tue Jul 24 14:32:44 2007
0e73038
--- src/ex_docmd.c	Tue Jul 24 15:47:01 2007
0e73038
***************
0e73038
*** 10817,10828 ****
0e73038
      exarg_T	*eap;
0e73038
  {
0e73038
      char_u	*p;
0e73038
      char_u	*end;
0e73038
      int		c;
0e73038
!     int		mi;
0e73038
  
0e73038
      if (eap->line2 <= 3)
0e73038
! 	mi = eap->line2 - 1;
0e73038
      else
0e73038
      {
0e73038
  	EMSG(e_invcmd);
0e73038
--- 10817,10829 ----
0e73038
      exarg_T	*eap;
0e73038
  {
0e73038
      char_u	*p;
0e73038
+     char_u	*g;
0e73038
      char_u	*end;
0e73038
      int		c;
0e73038
!     int		id;
0e73038
  
0e73038
      if (eap->line2 <= 3)
0e73038
! 	id = eap->line2;
0e73038
      else
0e73038
      {
0e73038
  	EMSG(e_invcmd);
0e73038
***************
0e73038
*** 10831,10843 ****
0e73038
  
0e73038
      /* First clear any old pattern. */
0e73038
      if (!eap->skip)
0e73038
!     {
0e73038
! 	vim_free(curwin->w_match[mi].regprog);
0e73038
! 	curwin->w_match[mi].regprog = NULL;
0e73038
! 	vim_free(curwin->w_match_pat[mi]);
0e73038
! 	curwin->w_match_pat[mi] = NULL;
0e73038
! 	redraw_later(SOME_VALID);	/* always need a redraw */
0e73038
!     }
0e73038
  
0e73038
      if (ends_excmd(*eap->arg))
0e73038
  	end = eap->arg;
0e73038
--- 10832,10838 ----
0e73038
  
0e73038
      /* First clear any old pattern. */
0e73038
      if (!eap->skip)
0e73038
! 	match_delete(curwin, id, FALSE);
0e73038
  
0e73038
      if (ends_excmd(*eap->arg))
0e73038
  	end = eap->arg;
0e73038
***************
0e73038
*** 10848,10862 ****
0e73038
      {
0e73038
  	p = skiptowhite(eap->arg);
0e73038
  	if (!eap->skip)
0e73038
! 	{
0e73038
! 	    curwin->w_match_id[mi] = syn_namen2id(eap->arg,
0e73038
! 							 (int)(p - eap->arg));
0e73038
! 	    if (curwin->w_match_id[mi] == 0)
0e73038
! 	    {
0e73038
! 		EMSG2(_(e_nogroup), eap->arg);
0e73038
! 		return;
0e73038
! 	    }
0e73038
! 	}
0e73038
  	p = skipwhite(p);
0e73038
  	if (*p == NUL)
0e73038
  	{
0e73038
--- 10843,10849 ----
0e73038
      {
0e73038
  	p = skiptowhite(eap->arg);
0e73038
  	if (!eap->skip)
0e73038
! 	    g = vim_strnsave(eap->arg, (int)(p - eap->arg));
0e73038
  	p = skipwhite(p);
0e73038
  	if (*p == NUL)
0e73038
  	{
0e73038
***************
0e73038
*** 10880,10893 ****
0e73038
  
0e73038
  	    c = *end;
0e73038
  	    *end = NUL;
0e73038
! 	    curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
0e73038
! 	    if (curwin->w_match[mi].regprog == NULL)
0e73038
! 	    {
0e73038
! 		EMSG2(_(e_invarg2), p);
0e73038
! 		*end = c;
0e73038
! 		return;
0e73038
! 	    }
0e73038
! 	    curwin->w_match_pat[mi] = vim_strsave(p + 1);
0e73038
  	    *end = c;
0e73038
  	}
0e73038
      }
0e73038
--- 10867,10874 ----
0e73038
  
0e73038
  	    c = *end;
0e73038
  	    *end = NUL;
0e73038
! 	    match_add(curwin, g, p + 1, 10, id);
0e73038
! 	    vim_free(g);
0e73038
  	    *end = c;
0e73038
  	}
0e73038
      }
0e73038
*** ../vim-7.1.039/src/proto/window.pro	Sat May  5 19:52:36 2007
0e73038
--- src/proto/window.pro	Tue Jul 24 16:38:19 2007
0e73038
***************
0e73038
*** 59,62 ****
0e73038
--- 59,66 ----
0e73038
  int only_one_window __ARGS((void));
0e73038
  void check_lnums __ARGS((int do_curwin));
0e73038
  int win_hasvertsplit __ARGS((void));
0e73038
+ int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
0e73038
+ int match_delete __ARGS((win_T *wp, int id, int perr));
0e73038
+ void clear_matches __ARGS((win_T *wp));
0e73038
+ matchitem_T *get_match __ARGS((win_T *wp, int id));
0e73038
  /* vim: set ft=c : */
0e73038
*** ../vim-7.1.039/src/screen.c	Tue Jun 19 17:49:12 2007
0e73038
--- src/screen.c	Thu Jul 26 21:55:40 2007
0e73038
***************
0e73038
*** 100,126 ****
0e73038
  static int	screen_cur_row, screen_cur_col;	/* last known cursor position */
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
- /*
0e73038
-  * Struct used for highlighting 'hlsearch' matches for the last use search
0e73038
-  * pattern or a ":match" item.
0e73038
-  * For 'hlsearch' there is one pattern for all windows.  For ":match" there is
0e73038
-  * a different pattern for each window.
0e73038
-  */
0e73038
- typedef struct
0e73038
- {
0e73038
-     regmmatch_T	rm;	/* points to the regexp program; contains last found
0e73038
- 			   match (may continue in next line) */
0e73038
-     buf_T	*buf;	/* the buffer to search for a match */
0e73038
-     linenr_T	lnum;	/* the line to search for a match */
0e73038
-     int		attr;	/* attributes to be used for a match */
0e73038
-     int		attr_cur; /* attributes currently active in win_line() */
0e73038
-     linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
0e73038
-     colnr_T	startcol; /* in win_line() points to char where HL starts */
0e73038
-     colnr_T	endcol;	 /* in win_line() points to char where HL ends */
0e73038
- } match_T;
0e73038
- 
0e73038
  static match_T search_hl;	/* used for 'hlsearch' highlight matching */
0e73038
- static match_T match_hl[3];	/* used for ":match" highlight matching */
0e73038
  #endif
0e73038
  
0e73038
  #ifdef FEAT_FOLDING
0e73038
--- 100,106 ----
0e73038
***************
0e73038
*** 155,160 ****
0e73038
--- 135,141 ----
0e73038
  static void redraw_custum_statusline __ARGS((win_T *wp));
0e73038
  #endif
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
+ #define SEARCH_HL_PRIORITY 0
0e73038
  static void start_search_hl __ARGS((void));
0e73038
  static void end_search_hl __ARGS((void));
0e73038
  static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
0e73038
***************
0e73038
*** 787,792 ****
0e73038
--- 768,774 ----
0e73038
  					   w_topline got smaller a bit */
0e73038
  #endif
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
+     matchitem_T *cur;		/* points to the match list */
0e73038
      int		top_to_mod = FALSE;    /* redraw above mod_top */
0e73038
  #endif
0e73038
  
0e73038
***************
0e73038
*** 848,865 ****
0e73038
  #endif
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     /* Setup for ":match" and 'hlsearch' highlighting.  Disable any previous
0e73038
       * match */
0e73038
!     for (i = 0; i < 3; ++i)
0e73038
      {
0e73038
! 	match_hl[i].rm = wp->w_match[i];
0e73038
! 	if (wp->w_match_id[i] == 0)
0e73038
! 	    match_hl[i].attr = 0;
0e73038
  	else
0e73038
! 	    match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
0e73038
! 	match_hl[i].buf = buf;
0e73038
! 	match_hl[i].lnum = 0;
0e73038
! 	match_hl[i].first_lnum = 0;
0e73038
      }
0e73038
      search_hl.buf = buf;
0e73038
      search_hl.lnum = 0;
0e73038
--- 830,849 ----
0e73038
  #endif
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     /* Setup for match and 'hlsearch' highlighting.  Disable any previous
0e73038
       * match */
0e73038
!     cur = wp->w_match_head;
0e73038
!     while (cur != NULL)
0e73038
      {
0e73038
! 	cur->hl.rm = cur->match;
0e73038
! 	if (cur->hlg_id == 0)
0e73038
! 	    cur->hl.attr = 0;
0e73038
  	else
0e73038
! 	    cur->hl.attr = syn_id2attr(cur->hlg_id);
0e73038
! 	cur->hl.buf = buf;
0e73038
! 	cur->hl.lnum = 0;
0e73038
! 	cur->hl.first_lnum = 0;
0e73038
! 	cur = cur->next;
0e73038
      }
0e73038
      search_hl.buf = buf;
0e73038
      search_hl.lnum = 0;
0e73038
***************
0e73038
*** 923,941 ****
0e73038
  	     * change in one line may make the Search highlighting in a
0e73038
  	     * previous line invalid.  Simple solution: redraw all visible
0e73038
  	     * lines above the change.
0e73038
! 	     * Same for a ":match" pattern.
0e73038
  	     */
0e73038
  	    if (search_hl.rm.regprog != NULL
0e73038
  					&& re_multiline(search_hl.rm.regprog))
0e73038
  		top_to_mod = TRUE;
0e73038
  	    else
0e73038
! 		for (i = 0; i < 3; ++i)
0e73038
! 		    if (match_hl[i].rm.regprog != NULL
0e73038
! 				      && re_multiline(match_hl[i].rm.regprog))
0e73038
  		    {
0e73038
  			top_to_mod = TRUE;
0e73038
  			break;
0e73038
  		    }
0e73038
  #endif
0e73038
  	}
0e73038
  #ifdef FEAT_FOLDING
0e73038
--- 907,931 ----
0e73038
  	     * change in one line may make the Search highlighting in a
0e73038
  	     * previous line invalid.  Simple solution: redraw all visible
0e73038
  	     * lines above the change.
0e73038
! 	     * Same for a match pattern.
0e73038
  	     */
0e73038
  	    if (search_hl.rm.regprog != NULL
0e73038
  					&& re_multiline(search_hl.rm.regprog))
0e73038
  		top_to_mod = TRUE;
0e73038
  	    else
0e73038
! 	    {
0e73038
! 		cur = wp->w_match_head;
0e73038
! 		while (cur != NULL)
0e73038
! 		{
0e73038
! 		    if (cur->match.regprog != NULL
0e73038
! 					   && re_multiline(cur->match.regprog))
0e73038
  		    {
0e73038
  			top_to_mod = TRUE;
0e73038
  			break;
0e73038
  		    }
0e73038
+ 		    cur = cur->next;
0e73038
+ 		}
0e73038
+ 	    }
0e73038
  #endif
0e73038
  	}
0e73038
  #ifdef FEAT_FOLDING
0e73038
***************
0e73038
*** 2626,2635 ****
0e73038
      int		line_attr = 0;		/* atrribute for the whole line */
0e73038
  #endif
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     match_T	*shl;			/* points to search_hl or match_hl */
0e73038
! #endif
0e73038
! #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
0e73038
!     int		i;
0e73038
  #endif
0e73038
  #ifdef FEAT_ARABIC
0e73038
      int		prev_c = 0;		/* previous Arabic character */
0e73038
--- 2634,2646 ----
0e73038
      int		line_attr = 0;		/* atrribute for the whole line */
0e73038
  #endif
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     matchitem_T *cur;			/* points to the match list */
0e73038
!     match_T	*shl;			/* points to search_hl or a match */
0e73038
!     int		shl_flag;		/* flag to indicate whether search_hl
0e73038
! 					   has been processed or not */
0e73038
!     int		prevcol_hl_flag;	/* flag to indicate whether prevcol
0e73038
! 					   equals startcol of search_hl or one
0e73038
! 					   of the matches */
0e73038
  #endif
0e73038
  #ifdef FEAT_ARABIC
0e73038
      int		prev_c = 0;		/* previous Arabic character */
0e73038
***************
0e73038
*** 3074,3085 ****
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
      /*
0e73038
!      * Handle highlighting the last used search pattern and ":match".
0e73038
!      * Do this for both search_hl and match_hl[3].
0e73038
       */
0e73038
!     for (i = 3; i >= 0; --i)
0e73038
      {
0e73038
! 	shl = (i == 3) ? &search_hl : &match_hl[i];
0e73038
  	shl->startcol = MAXCOL;
0e73038
  	shl->endcol = MAXCOL;
0e73038
  	shl->attr_cur = 0;
0e73038
--- 3085,3104 ----
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
      /*
0e73038
!      * Handle highlighting the last used search pattern and matches.
0e73038
!      * Do this for both search_hl and the match list.
0e73038
       */
0e73038
!     cur = wp->w_match_head;
0e73038
!     shl_flag = FALSE;
0e73038
!     while (cur != NULL || shl_flag == FALSE)
0e73038
      {
0e73038
! 	if (shl_flag == FALSE)
0e73038
! 	{
0e73038
! 	    shl = &search_hl;
0e73038
! 	    shl_flag = TRUE;
0e73038
! 	}
0e73038
! 	else
0e73038
! 	    shl = &cur->hl;
0e73038
  	shl->startcol = MAXCOL;
0e73038
  	shl->endcol = MAXCOL;
0e73038
  	shl->attr_cur = 0;
0e73038
***************
0e73038
*** 3122,3127 ****
0e73038
--- 3141,3148 ----
0e73038
  		area_highlighting = TRUE;
0e73038
  	    }
0e73038
  	}
0e73038
+ 	if (shl != &search_hl && cur != NULL)
0e73038
+ 	    cur = cur->next;
0e73038
      }
0e73038
  #endif
0e73038
  
0e73038
***************
0e73038
*** 3388,3400 ****
0e73038
  		 * After end, check for start/end of next match.
0e73038
  		 * When another match, have to check for start again.
0e73038
  		 * Watch out for matching an empty string!
0e73038
! 		 * Do this first for search_hl, then for match_hl, so that
0e73038
! 		 * ":match" overrules 'hlsearch'.
0e73038
  		 */
0e73038
  		v = (long)(ptr - line);
0e73038
! 		for (i = 3; i >= 0; --i)
0e73038
! 		{
0e73038
! 		    shl = (i == 3) ? &search_hl : &match_hl[i];
0e73038
  		    while (shl->rm.regprog != NULL)
0e73038
  		    {
0e73038
  			if (shl->startcol != MAXCOL
0e73038
--- 3409,3432 ----
0e73038
  		 * After end, check for start/end of next match.
0e73038
  		 * When another match, have to check for start again.
0e73038
  		 * Watch out for matching an empty string!
0e73038
! 		 * Do this for 'search_hl' and the match list (ordered by
0e73038
! 		 * priority).
0e73038
  		 */
0e73038
  		v = (long)(ptr - line);
0e73038
! 		cur = wp->w_match_head;
0e73038
! 		shl_flag = FALSE;
0e73038
! 		while (cur != NULL || shl_flag == FALSE)
0e73038
! 		{
0e73038
! 		    if (shl_flag == FALSE
0e73038
! 			    && ((cur != NULL
0e73038
! 				    && cur->priority > SEARCH_HL_PRIORITY)
0e73038
! 				|| cur == NULL))
0e73038
! 		    {
0e73038
! 			shl = &search_hl;
0e73038
! 			shl_flag = TRUE;
0e73038
! 		    }
0e73038
! 		    else
0e73038
! 			shl = &cur->hl;
0e73038
  		    while (shl->rm.regprog != NULL)
0e73038
  		    {
0e73038
  			if (shl->startcol != MAXCOL
0e73038
***************
0e73038
*** 3442,3458 ****
0e73038
  			}
0e73038
  			break;
0e73038
  		    }
0e73038
  		}
0e73038
  
0e73038
! 		/* ":match" highlighting overrules 'hlsearch' */
0e73038
! 		for (i = 0; i <= 3; ++i)
0e73038
! 		    if (i == 3)
0e73038
! 			search_attr = search_hl.attr_cur;
0e73038
! 		    else if (match_hl[i].attr_cur != 0)
0e73038
  		    {
0e73038
! 			search_attr = match_hl[i].attr_cur;
0e73038
! 			break;
0e73038
  		    }
0e73038
  	    }
0e73038
  #endif
0e73038
  
0e73038
--- 3474,3505 ----
0e73038
  			}
0e73038
  			break;
0e73038
  		    }
0e73038
+ 		    if (shl != &search_hl && cur != NULL)
0e73038
+ 			cur = cur->next;
0e73038
  		}
0e73038
  
0e73038
! 		/* Use attributes from match with highest priority among
0e73038
! 		 * 'search_hl' and the match list. */
0e73038
! 		search_attr = search_hl.attr_cur;
0e73038
! 		cur = wp->w_match_head;
0e73038
! 		shl_flag = FALSE;
0e73038
! 		while (cur != NULL || shl_flag == FALSE)
0e73038
! 		{
0e73038
! 		    if (shl_flag == FALSE
0e73038
! 			    && ((cur != NULL
0e73038
! 				    && cur->priority > SEARCH_HL_PRIORITY)
0e73038
! 				|| cur == NULL))
0e73038
  		    {
0e73038
! 			shl = &search_hl;
0e73038
! 			shl_flag = TRUE;
0e73038
  		    }
0e73038
+ 		    else
0e73038
+ 			shl = &cur->hl;
0e73038
+ 		    if (shl->attr_cur != 0)
0e73038
+ 			search_attr = shl->attr_cur;
0e73038
+ 		    if (shl != &search_hl && cur != NULL)
0e73038
+ 			cur = cur->next;
0e73038
+ 		}
0e73038
  	    }
0e73038
  #endif
0e73038
  
0e73038
***************
0e73038
*** 3613,3618 ****
0e73038
--- 3660,3667 ----
0e73038
  			 * Draw it as a space with a composing char. */
0e73038
  			if (utf_iscomposing(mb_c))
0e73038
  			{
0e73038
+ 			    int i;
0e73038
+ 
0e73038
  			    for (i = Screen_mco - 1; i > 0; --i)
0e73038
  				u8cc[i] = u8cc[i - 1];
0e73038
  			    u8cc[0] = mb_c;
0e73038
***************
0e73038
*** 4256,4269 ****
0e73038
  	     * highlight match at end of line. If it's beyond the last
0e73038
  	     * char on the screen, just overwrite that one (tricky!)  Not
0e73038
  	     * needed when a '$' was displayed for 'list'. */
0e73038
  	    if (lcs_eol == lcs_eol_one
0e73038
  		    && ((area_attr != 0 && vcol == fromcol && c == NUL)
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
  			/* highlight 'hlsearch' match at end of line */
0e73038
! 			|| ((prevcol == (long)search_hl.startcol
0e73038
! 				|| prevcol == (long)match_hl[0].startcol
0e73038
! 				|| prevcol == (long)match_hl[1].startcol
0e73038
! 				|| prevcol == (long)match_hl[2].startcol)
0e73038
  # if defined(LINE_ATTR)
0e73038
  			    && did_line_attr <= 1
0e73038
  # endif
0e73038
--- 4305,4333 ----
0e73038
  	     * highlight match at end of line. If it's beyond the last
0e73038
  	     * char on the screen, just overwrite that one (tricky!)  Not
0e73038
  	     * needed when a '$' was displayed for 'list'. */
0e73038
+ #ifdef FEAT_SEARCH_EXTRA
0e73038
+ 	    prevcol_hl_flag = FALSE;
0e73038
+ 	    if (prevcol == (long)search_hl.startcol)
0e73038
+ 		prevcol_hl_flag = TRUE;
0e73038
+ 	    else
0e73038
+ 	    {
0e73038
+ 		cur = wp->w_match_head;
0e73038
+ 		while (cur != NULL)
0e73038
+ 		{
0e73038
+ 		    if (prevcol == (long)cur->hl.startcol)
0e73038
+ 		    {
0e73038
+ 			prevcol_hl_flag = TRUE;
0e73038
+ 			break;
0e73038
+ 		    }
0e73038
+ 		    cur = cur->next;
0e73038
+ 		}
0e73038
+ 	    }
0e73038
+ #endif
0e73038
  	    if (lcs_eol == lcs_eol_one
0e73038
  		    && ((area_attr != 0 && vcol == fromcol && c == NUL)
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
  			/* highlight 'hlsearch' match at end of line */
0e73038
! 			|| (prevcol_hl_flag == TRUE
0e73038
  # if defined(LINE_ATTR)
0e73038
  			    && did_line_attr <= 1
0e73038
  # endif
0e73038
***************
0e73038
*** 4304,4318 ****
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
  		if (area_attr == 0)
0e73038
  		{
0e73038
! 		    for (i = 0; i <= 3; ++i)
0e73038
! 		    {
0e73038
! 			if (i == 3)
0e73038
! 			    char_attr = search_hl.attr;
0e73038
! 			else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
0e73038
  			{
0e73038
! 			    char_attr = match_hl[i].attr;
0e73038
! 			    break;
0e73038
  			}
0e73038
  		    }
0e73038
  		}
0e73038
  #endif
0e73038
--- 4368,4394 ----
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
  		if (area_attr == 0)
0e73038
  		{
0e73038
! 		    /* Use attributes from match with highest priority among
0e73038
! 		     * 'search_hl' and the match list. */
0e73038
! 		    char_attr = search_hl.attr;
0e73038
! 		    cur = wp->w_match_head;
0e73038
! 		    shl_flag = FALSE;
0e73038
! 		    while (cur != NULL || shl_flag == FALSE)
0e73038
! 		    {
0e73038
! 			if (shl_flag == FALSE
0e73038
! 				&& ((cur != NULL
0e73038
! 					&& cur->priority > SEARCH_HL_PRIORITY)
0e73038
! 				    || cur == NULL))
0e73038
  			{
0e73038
! 			    shl = &search_hl;
0e73038
! 			    shl_flag = TRUE;
0e73038
  			}
0e73038
+ 			else
0e73038
+ 			    shl = &cur->hl;
0e73038
+ 			if ((ptr - line) - 1 == (long)shl->startcol)
0e73038
+ 			    char_attr = shl->attr;
0e73038
+ 			if (shl != &search_hl && cur != NULL)
0e73038
+ 			    cur = cur->next;
0e73038
  		    }
0e73038
  		}
0e73038
  #endif
0e73038
***************
0e73038
*** 4462,4467 ****
0e73038
--- 4538,4545 ----
0e73038
  	    {
0e73038
  		if (mb_utf8)
0e73038
  		{
0e73038
+ 		    int i;
0e73038
+ 
0e73038
  		    ScreenLinesUC[off] = mb_c;
0e73038
  		    if ((c & 0xff) == 0)
0e73038
  			ScreenLines[off] = 0x80;   /* avoid storing zero */
0e73038
***************
0e73038
*** 6320,6326 ****
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
  /*
0e73038
!  * Prepare for 'searchhl' highlighting.
0e73038
   */
0e73038
      static void
0e73038
  start_search_hl()
0e73038
--- 6398,6404 ----
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
  /*
0e73038
!  * Prepare for 'hlsearch' highlighting.
0e73038
   */
0e73038
      static void
0e73038
  start_search_hl()
0e73038
***************
0e73038
*** 6333,6339 ****
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
!  * Clean up for 'searchhl' highlighting.
0e73038
   */
0e73038
      static void
0e73038
  end_search_hl()
0e73038
--- 6411,6417 ----
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
!  * Clean up for 'hlsearch' highlighting.
0e73038
   */
0e73038
      static void
0e73038
  end_search_hl()
0e73038
***************
0e73038
*** 6353,6370 ****
0e73038
      win_T	*wp;
0e73038
      linenr_T	lnum;
0e73038
  {
0e73038
!     match_T	*shl;		/* points to search_hl or match_hl */
0e73038
      int		n;
0e73038
-     int		i;
0e73038
  
0e73038
      /*
0e73038
       * When using a multi-line pattern, start searching at the top
0e73038
       * of the window or just after a closed fold.
0e73038
!      * Do this both for search_hl and match_hl[3].
0e73038
       */
0e73038
!     for (i = 3; i >= 0; --i)
0e73038
      {
0e73038
! 	shl = (i == 3) ? &search_hl : &match_hl[i];
0e73038
  	if (shl->rm.regprog != NULL
0e73038
  		&& shl->lnum == 0
0e73038
  		&& re_multiline(shl->rm.regprog))
0e73038
--- 6431,6458 ----
0e73038
      win_T	*wp;
0e73038
      linenr_T	lnum;
0e73038
  {
0e73038
!     matchitem_T *cur;		/* points to the match list */
0e73038
!     match_T	*shl;		/* points to search_hl or a match */
0e73038
!     int		shl_flag;	/* flag to indicate whether search_hl
0e73038
! 				   has been processed or not */
0e73038
      int		n;
0e73038
  
0e73038
      /*
0e73038
       * When using a multi-line pattern, start searching at the top
0e73038
       * of the window or just after a closed fold.
0e73038
!      * Do this both for search_hl and the match list.
0e73038
       */
0e73038
!     cur = wp->w_match_head;
0e73038
!     shl_flag = FALSE;
0e73038
!     while (cur != NULL || shl_flag == FALSE)
0e73038
      {
0e73038
! 	if (shl_flag == FALSE)
0e73038
! 	{
0e73038
! 	    shl = &search_hl;
0e73038
! 	    shl_flag = TRUE;
0e73038
! 	}
0e73038
! 	else
0e73038
! 	    shl = &cur->hl;
0e73038
  	if (shl->rm.regprog != NULL
0e73038
  		&& shl->lnum == 0
0e73038
  		&& re_multiline(shl->rm.regprog))
0e73038
***************
0e73038
*** 6399,6409 ****
0e73038
  		}
0e73038
  	    }
0e73038
  	}
0e73038
      }
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
!  * Search for a next 'searchl' or ":match" match.
0e73038
   * Uses shl->buf.
0e73038
   * Sets shl->lnum and shl->rm contents.
0e73038
   * Note: Assumes a previous match is always before "lnum", unless
0e73038
--- 6487,6499 ----
0e73038
  		}
0e73038
  	    }
0e73038
  	}
0e73038
+ 	if (shl != &search_hl && cur != NULL)
0e73038
+ 	    cur = cur->next;
0e73038
      }
0e73038
  }
0e73038
  
0e73038
  /*
0e73038
!  * Search for a next 'hlsearch' or match.
0e73038
   * Uses shl->buf.
0e73038
   * Sets shl->lnum and shl->rm contents.
0e73038
   * Note: Assumes a previous match is always before "lnum", unless
0e73038
***************
0e73038
*** 6413,6419 ****
0e73038
      static void
0e73038
  next_search_hl(win, shl, lnum, mincol)
0e73038
      win_T	*win;
0e73038
!     match_T	*shl;		/* points to search_hl or match_hl */
0e73038
      linenr_T	lnum;
0e73038
      colnr_T	mincol;		/* minimal column for a match */
0e73038
  {
0e73038
--- 6503,6509 ----
0e73038
      static void
0e73038
  next_search_hl(win, shl, lnum, mincol)
0e73038
      win_T	*win;
0e73038
!     match_T	*shl;		/* points to search_hl or a match */
0e73038
      linenr_T	lnum;
0e73038
      colnr_T	mincol;		/* minimal column for a match */
0e73038
  {
0e73038
***************
0e73038
*** 6481,6487 ****
0e73038
  	    /* Error while handling regexp: stop using this regexp. */
0e73038
  	    if (shl == &search_hl)
0e73038
  	    {
0e73038
! 		/* don't free the regprog in match_hl[], it's a copy */
0e73038
  		vim_free(shl->rm.regprog);
0e73038
  		no_hlsearch = TRUE;
0e73038
  	    }
0e73038
--- 6571,6577 ----
0e73038
  	    /* Error while handling regexp: stop using this regexp. */
0e73038
  	    if (shl == &search_hl)
0e73038
  	    {
0e73038
! 		/* don't free regprog in the match list, it's a copy */
0e73038
  		vim_free(shl->rm.regprog);
0e73038
  		no_hlsearch = TRUE;
0e73038
  	    }
0e73038
*** ../vim-7.1.039/src/structs.h	Thu May 10 20:32:30 2007
0e73038
--- src/structs.h	Wed Jul 25 21:08:46 2007
0e73038
***************
0e73038
*** 1694,1699 ****
0e73038
--- 1694,1734 ----
0e73038
  #define FR_COL	2	/* frame with a column of windows */
0e73038
  
0e73038
  /*
0e73038
+  * Struct used for highlighting 'hlsearch' matches, matches defined by
0e73038
+  * ":match" and matches defined by match functions.
0e73038
+  * For 'hlsearch' there is one pattern for all windows.  For ":match" and the
0e73038
+  * match functions there is a different pattern for each window.
0e73038
+  */
0e73038
+ typedef struct
0e73038
+ {
0e73038
+     regmmatch_T	rm;	/* points to the regexp program; contains last found
0e73038
+ 			   match (may continue in next line) */
0e73038
+     buf_T	*buf;	/* the buffer to search for a match */
0e73038
+     linenr_T	lnum;	/* the line to search for a match */
0e73038
+     int		attr;	/* attributes to be used for a match */
0e73038
+     int		attr_cur; /* attributes currently active in win_line() */
0e73038
+     linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
0e73038
+     colnr_T	startcol; /* in win_line() points to char where HL starts */
0e73038
+     colnr_T	endcol;	 /* in win_line() points to char where HL ends */
0e73038
+ } match_T;
0e73038
+ 
0e73038
+ /*
0e73038
+  * matchitem_T provides a linked list for storing match items for ":match" and
0e73038
+  * the match functions.
0e73038
+  */
0e73038
+ typedef struct matchitem matchitem_T;
0e73038
+ struct matchitem
0e73038
+ {
0e73038
+     matchitem_T	*next;
0e73038
+     int		id;	    /* match ID */
0e73038
+     int		priority;   /* match priority */
0e73038
+     char_u	*pattern;   /* pattern to highlight */
0e73038
+     int		hlg_id;	    /* highlight group ID */
0e73038
+     regmmatch_T	match;	    /* regexp program for pattern */
0e73038
+     match_T	hl;	    /* struct for doing the actual highlighting */
0e73038
+ };
0e73038
+ 
0e73038
+ /*
0e73038
   * Structure which contains all information that belongs to a window
0e73038
   *
0e73038
   * All row numbers are relative to the start of the window, except w_winrow.
0e73038
***************
0e73038
*** 1934,1942 ****
0e73038
  #endif
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     regmmatch_T	w_match[3];	    /* regexp programs for ":match" */
0e73038
!     char_u	*(w_match_pat[3]);  /* patterns for ":match" */
0e73038
!     int		w_match_id[3];	    /* highlight IDs for ":match" */
0e73038
  #endif
0e73038
  
0e73038
      /*
0e73038
--- 1969,1976 ----
0e73038
  #endif
0e73038
  
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     matchitem_T	*w_match_head;		/* head of match list */
0e73038
!     int		w_next_match_id;	/* next match ID */
0e73038
  #endif
0e73038
  
0e73038
      /*
0e73038
*** ../vim-7.1.039/src/syntax.c	Tue Jul 24 14:32:44 2007
0e73038
--- src/syntax.c	Tue Jul 24 15:47:01 2007
0e73038
***************
0e73038
*** 8504,8510 ****
0e73038
  syn_id2name(id)
0e73038
      int		id;
0e73038
  {
0e73038
!     if (id <= 0 || id >= highlight_ga.ga_len)
0e73038
  	return (char_u *)"";
0e73038
      return HL_TABLE()[id - 1].sg_name;
0e73038
  }
0e73038
--- 8504,8510 ----
0e73038
  syn_id2name(id)
0e73038
      int		id;
0e73038
  {
0e73038
!     if (id <= 0 || id > highlight_ga.ga_len)
0e73038
  	return (char_u *)"";
0e73038
      return HL_TABLE()[id - 1].sg_name;
0e73038
  }
0e73038
*** ../vim-7.1.039/src/testdir/Makefile	Sun Apr 30 20:48:47 2006
0e73038
--- src/testdir/Makefile	Tue Jul 24 15:34:33 2007
0e73038
***************
0e73038
*** 1,5 ****
0e73038
  #
0e73038
! # Makefile to run al tests for Vim
0e73038
  #
0e73038
  
0e73038
  VIMPROG = ../vim
0e73038
--- 1,5 ----
0e73038
  #
0e73038
! # Makefile to run all tests for Vim
0e73038
  #
0e73038
  
0e73038
  VIMPROG = ../vim
0e73038
***************
0e73038
*** 15,21 ****
0e73038
  		test43.out test44.out test45.out test46.out test47.out \
0e73038
  		test48.out test49.out test51.out test52.out test53.out \
0e73038
  		test54.out test55.out test56.out test57.out test58.out \
0e73038
! 		test59.out test60.out test61.out test62.out
0e73038
  
0e73038
  SCRIPTS_GUI = test16.out
0e73038
  
0e73038
--- 15,21 ----
0e73038
  		test43.out test44.out test45.out test46.out test47.out \
0e73038
  		test48.out test49.out test51.out test52.out test53.out \
0e73038
  		test54.out test55.out test56.out test57.out test58.out \
0e73038
! 		test59.out test60.out test61.out test62.out test63.out
0e73038
  
0e73038
  SCRIPTS_GUI = test16.out
0e73038
  
0e73038
*** ../vim-7.1.039/src/testdir/test63.in	Tue Jul 24 16:45:02 2007
0e73038
--- src/testdir/test63.in	Tue Jul 24 15:32:30 2007
0e73038
***************
0e73038
*** 0 ****
0e73038
--- 1,157 ----
0e73038
+ Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
0e73038
+ "matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
0e73038
+ 
0e73038
+ STARTTEST
0e73038
+ :so small.vim
0e73038
+ :" --- Check that "matcharg()" returns the correct group and pattern if a match
0e73038
+ :" --- is defined.
0e73038
+ :let @r = "*** Test 1: "
0e73038
+ :highlight MyGroup1 ctermbg=red
0e73038
+ :highlight MyGroup2 ctermbg=green
0e73038
+ :highlight MyGroup3 ctermbg=blue
0e73038
+ :match MyGroup1 /TODO/
0e73038
+ :2match MyGroup2 /FIXME/
0e73038
+ :3match MyGroup3 /XXX/
0e73038
+ :if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :" --- Check that "matcharg()" returns an empty list if the argument is not 1,
0e73038
+ :" --- 2 or 3 (only 0 and 4 are tested).
0e73038
+ :let @r .= "*** Test 2: "
0e73038
+ :if matcharg(0) == [] && matcharg(4) == []
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
0e73038
+ :let @r .= "*** Test 3: "
0e73038
+ :match
0e73038
+ :2match
0e73038
+ :3match
0e73038
+ :if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :" --- Check that "matchadd()" and "getmatches()" agree on added matches and
0e73038
+ :" --- that default values apply.
0e73038
+ :let @r .= "*** Test 4: "
0e73038
+ :let m1 = matchadd("MyGroup1", "TODO")
0e73038
+ :let m2 = matchadd("MyGroup2", "FIXME", 42)
0e73038
+ :let m3 = matchadd("MyGroup3", "XXX", 60, 17)
0e73038
+ :if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :" --- Check that "matchdelete()" deletes the matches defined in the previous
0e73038
+ :" --- test correctly.
0e73038
+ :let @r .= "*** Test 5: "
0e73038
+ :call matchdelete(m1)
0e73038
+ :call matchdelete(m2)
0e73038
+ :call matchdelete(m3)
0e73038
+ :unlet m1
0e73038
+ :unlet m2
0e73038
+ :unlet m3
0e73038
+ :if getmatches() == []
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :" --- Check that "matchdelete()" returns 0 if succesfull and otherwise -1.
0e73038
+ :let @r .= "*** Test 6: "
0e73038
+ :let m = matchadd("MyGroup1", "TODO")
0e73038
+ :let r1 = matchdelete(m)
0e73038
+ :let r2 = matchdelete(42)
0e73038
+ :if r1 == 0 && r2 == -1
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :unlet m
0e73038
+ :unlet r1
0e73038
+ :unlet r2
0e73038
+ :" --- Check that "clearmatches()" clears all matches defined by ":match" and
0e73038
+ :" --- "matchadd()".
0e73038
+ :let @r .= "*** Test 7: "
0e73038
+ :let m1 = matchadd("MyGroup1", "TODO")
0e73038
+ :let m2 = matchadd("MyGroup2", "FIXME", 42)
0e73038
+ :let m3 = matchadd("MyGroup3", "XXX", 60, 17)
0e73038
+ :match MyGroup1 /COFFEE/
0e73038
+ :2match MyGroup2 /HUMPPA/
0e73038
+ :3match MyGroup3 /VIM/
0e73038
+ :call clearmatches()
0e73038
+ :if getmatches() == []
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :unlet m1
0e73038
+ :unlet m2
0e73038
+ :unlet m3
0e73038
+ :" --- Check that "setmatches()" restores a list of matches saved by
0e73038
+ :" --- "getmatches()" without changes. (Matches with equal priority must also
0e73038
+ :" --- remain in the same order.)
0e73038
+ :let @r .= "*** Test 8: "
0e73038
+ :let m1 = matchadd("MyGroup1", "TODO")
0e73038
+ :let m2 = matchadd("MyGroup2", "FIXME", 42)
0e73038
+ :let m3 = matchadd("MyGroup3", "XXX", 60, 17)
0e73038
+ :match MyGroup1 /COFFEE/
0e73038
+ :2match MyGroup2 /HUMPPA/
0e73038
+ :3match MyGroup3 /VIM/
0e73038
+ :let ml = getmatches()
0e73038
+ :call clearmatches()
0e73038
+ :call setmatches(ml)
0e73038
+ :if getmatches() == ml
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :call clearmatches()
0e73038
+ :unlet m1
0e73038
+ :unlet m2
0e73038
+ :unlet m3
0e73038
+ :unlet ml
0e73038
+ :" --- Check that "setmatches()" will not add two matches with the same ID. The
0e73038
+ :" --- expected behaviour (for now) is to add the first match but not the
0e73038
+ :" --- second and to return 0 (even though it is a matter of debate whether
0e73038
+ :" --- this can be considered succesfull behaviour).
0e73038
+ :let @r .= "*** Test 9: "
0e73038
+ :let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
0e73038
+ :if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :call clearmatches()
0e73038
+ :unlet r1
0e73038
+ :" --- Check that "setmatches()" returns 0 if succesfull and otherwise -1.
0e73038
+ :" --- (A range of valid and invalid input values are tried out to generate the
0e73038
+ :" --- return values.)
0e73038
+ :let @r .= "*** Test 10: "
0e73038
+ :let rs1 = setmatches([])
0e73038
+ :let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
0e73038
+ :call clearmatches()
0e73038
+ :let rf1 = setmatches(0)
0e73038
+ :let rf2 = setmatches([0])
0e73038
+ :let rf3 = setmatches([{'wrong key': 'wrong value'}])
0e73038
+ :if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
0e73038
+ :  let @r .= "OK\n"
0e73038
+ :else
0e73038
+ :  let @r .= "FAILED\n"
0e73038
+ :endif
0e73038
+ :unlet rs1
0e73038
+ :unlet rs2
0e73038
+ :unlet rf1
0e73038
+ :unlet rf2
0e73038
+ :unlet rf3
0e73038
+ :highlight clear MyGroup1
0e73038
+ :highlight clear MyGroup2
0e73038
+ :highlight clear MyGroup3
0e73038
+ G"rp
0e73038
+ :/^Results/,$wq! test.out
0e73038
+ ENDTEST
0e73038
+ 
0e73038
+ Results of test63:
0e73038
*** ../vim-7.1.039/src/testdir/test63.ok	Tue Jul 24 16:45:02 2007
0e73038
--- src/testdir/test63.ok	Tue Jul 24 15:32:30 2007
0e73038
***************
0e73038
*** 0 ****
0e73038
--- 1,11 ----
0e73038
+ Results of test63:
0e73038
+ *** Test 1: OK
0e73038
+ *** Test 2: OK
0e73038
+ *** Test 3: OK
0e73038
+ *** Test 4: OK
0e73038
+ *** Test 5: OK
0e73038
+ *** Test 6: OK
0e73038
+ *** Test 7: OK
0e73038
+ *** Test 8: OK
0e73038
+ *** Test 9: OK
0e73038
+ *** Test 10: OK
0e73038
*** ../vim-7.1.039/src/window.c	Thu May 10 18:42:26 2007
0e73038
--- src/window.c	Tue Jul 24 20:38:58 2007
0e73038
***************
0e73038
*** 75,80 ****
0e73038
--- 75,81 ----
0e73038
  static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
0e73038
  
0e73038
  #endif /* FEAT_WINDOWS */
0e73038
+ 
0e73038
  static win_T *win_alloc __ARGS((win_T *after));
0e73038
  static void win_new_height __ARGS((win_T *, int));
0e73038
  
0e73038
***************
0e73038
*** 4128,4133 ****
0e73038
--- 4129,4138 ----
0e73038
  #ifdef FEAT_AUTOCMD
0e73038
  	--autocmd_block;
0e73038
  #endif
0e73038
+ #ifdef FEAT_SEARCH_EXTRA
0e73038
+ 	newwin->w_match_head = NULL;
0e73038
+ 	newwin->w_next_match_id = 4;
0e73038
+ #endif
0e73038
      }
0e73038
      return newwin;
0e73038
  }
0e73038
***************
0e73038
*** 4185,4195 ****
0e73038
  	vim_free(wp->w_tagstack[i].tagname);
0e73038
  
0e73038
      vim_free(wp->w_localdir);
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     vim_free(wp->w_match[0].regprog);
0e73038
!     vim_free(wp->w_match[1].regprog);
0e73038
!     vim_free(wp->w_match[2].regprog);
0e73038
  #endif
0e73038
  #ifdef FEAT_JUMPLIST
0e73038
      free_jumplist(wp);
0e73038
  #endif
0e73038
--- 4190,4200 ----
0e73038
  	vim_free(wp->w_tagstack[i].tagname);
0e73038
  
0e73038
      vim_free(wp->w_localdir);
0e73038
+ 
0e73038
  #ifdef FEAT_SEARCH_EXTRA
0e73038
!     clear_matches(wp);
0e73038
  #endif
0e73038
+ 
0e73038
  #ifdef FEAT_JUMPLIST
0e73038
      free_jumplist(wp);
0e73038
  #endif
0e73038
***************
0e73038
*** 6172,6176 ****
0e73038
--- 6177,6351 ----
0e73038
  		return TRUE;
0e73038
  
0e73038
      return FALSE;
0e73038
+ }
0e73038
+ #endif
0e73038
+ 
0e73038
+ #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
0e73038
+ /*
0e73038
+  * Add match to the match list of window 'wp'.  The pattern 'pat' will be
0e73038
+  * highligted with the group 'grp' with priority 'prio'.
0e73038
+  * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
0e73038
+  * If no particular ID is desired, -1 must be specified for 'id'.
0e73038
+  * Return ID of added match, -1 on failure.
0e73038
+  */
0e73038
+     int
0e73038
+ match_add(wp, grp, pat, prio, id)
0e73038
+     win_T	*wp;
0e73038
+     char_u	*grp;
0e73038
+     char_u	*pat;
0e73038
+     int		prio;
0e73038
+     int		id;
0e73038
+ {
0e73038
+     matchitem_T *cur;
0e73038
+     matchitem_T *prev;
0e73038
+     matchitem_T *m;
0e73038
+     int		hlg_id;
0e73038
+     regmmatch_T match;
0e73038
+ 
0e73038
+     if (*grp == NUL || *pat == NUL)
0e73038
+ 	return -1;
0e73038
+     if (id < -1 || id == 0)
0e73038
+     {
0e73038
+ 	EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
0e73038
+ 	return -1;
0e73038
+     }
0e73038
+     if (id != -1)
0e73038
+     {
0e73038
+ 	cur = wp->w_match_head;
0e73038
+ 	while (cur != NULL)
0e73038
+ 	{
0e73038
+ 	    if (cur->id == id)
0e73038
+ 	    {
0e73038
+ 		EMSGN("E801: ID already taken: %ld", id);
0e73038
+ 		return -1;
0e73038
+ 	    }
0e73038
+ 	    cur = cur->next;
0e73038
+ 	}
0e73038
+     }
0e73038
+     if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
0e73038
+     {
0e73038
+ 	EMSG2(_(e_nogroup), grp);
0e73038
+ 	return -1;
0e73038
+     }
0e73038
+     if ((match.regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
0e73038
+     {
0e73038
+ 	EMSG2(_(e_invarg2), pat);
0e73038
+ 	return -1;
0e73038
+     }
0e73038
+ 
0e73038
+     /* Find available match ID. */
0e73038
+     while (id == -1)
0e73038
+     {
0e73038
+ 	cur = wp->w_match_head;
0e73038
+ 	while (cur != NULL && cur->id != wp->w_next_match_id)
0e73038
+ 	    cur = cur->next;
0e73038
+ 	if (cur == NULL)
0e73038
+ 	    id = wp->w_next_match_id;
0e73038
+ 	wp->w_next_match_id++;
0e73038
+     }
0e73038
+ 
0e73038
+     /* Build new match. */
0e73038
+     m = (matchitem_T *)alloc(sizeof(matchitem_T));
0e73038
+     m->id = id;
0e73038
+     m->priority = prio;
0e73038
+     m->pattern = vim_strsave(pat);
0e73038
+     m->hlg_id = hlg_id;
0e73038
+     m->match.regprog = match.regprog;
0e73038
+ 
0e73038
+     /* Insert new match.  The match list is in ascending order with regard to
0e73038
+      * the match priorities. */
0e73038
+     cur = wp->w_match_head;
0e73038
+     prev = cur;
0e73038
+     while (cur != NULL && prio >= cur->priority)
0e73038
+     {
0e73038
+ 	prev = cur;
0e73038
+ 	cur = cur->next;
0e73038
+     }
0e73038
+     if (cur == prev)
0e73038
+ 	wp->w_match_head = m;
0e73038
+     else
0e73038
+ 	prev->next = m;
0e73038
+     m->next = cur;
0e73038
+ 
0e73038
+     redraw_later(SOME_VALID);
0e73038
+     return id;
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
+  * Delete match with ID 'id' in the match list of window 'wp'.
0e73038
+  * Print error messages if 'perr' is TRUE.
0e73038
+  */
0e73038
+     int
0e73038
+ match_delete(wp, id, perr)
0e73038
+     win_T	*wp;
0e73038
+     int		id;
0e73038
+     int		perr;
0e73038
+ {
0e73038
+     matchitem_T *cur = wp->w_match_head;
0e73038
+     matchitem_T *prev = cur;
0e73038
+ 
0e73038
+     if (id < 1)
0e73038
+     {
0e73038
+ 	if (perr == TRUE)
0e73038
+ 	    EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
0e73038
+ 									  id);
0e73038
+ 	return -1;
0e73038
+     }
0e73038
+     while (cur != NULL && cur->id != id)
0e73038
+     {
0e73038
+ 	prev = cur;
0e73038
+ 	cur = cur->next;
0e73038
+     }
0e73038
+     if (cur == NULL)
0e73038
+     {
0e73038
+ 	if (perr == TRUE)
0e73038
+ 	    EMSGN("E803: ID not found: %ld", id);
0e73038
+ 	return -1;
0e73038
+     }
0e73038
+     if (cur == prev)
0e73038
+ 	wp->w_match_head = cur->next;
0e73038
+     else
0e73038
+ 	prev->next = cur->next;
0e73038
+     vim_free(cur->match.regprog);
0e73038
+     vim_free(cur->pattern);
0e73038
+     vim_free(cur);
0e73038
+     redraw_later(SOME_VALID);
0e73038
+     return 0;
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
+  * Delete all matches in the match list of window 'wp'.
0e73038
+  */
0e73038
+     void
0e73038
+ clear_matches(wp)
0e73038
+     win_T	*wp;
0e73038
+ {
0e73038
+     matchitem_T *m;
0e73038
+ 
0e73038
+     while (wp->w_match_head != NULL)
0e73038
+     {
0e73038
+ 	m = wp->w_match_head->next;
0e73038
+ 	vim_free(wp->w_match_head->match.regprog);
0e73038
+ 	vim_free(wp->w_match_head->pattern);
0e73038
+ 	vim_free(wp->w_match_head);
0e73038
+ 	wp->w_match_head = m;
0e73038
+     }
0e73038
+     redraw_later(SOME_VALID);
0e73038
+ }
0e73038
+ 
0e73038
+ /*
0e73038
+  * Get match from ID 'id' in window 'wp'.
0e73038
+  * Return NULL if match not found.
0e73038
+  */
0e73038
+     matchitem_T *
0e73038
+ get_match(wp, id)
0e73038
+     win_T	*wp;
0e73038
+     int		id;
0e73038
+ {
0e73038
+     matchitem_T *cur = wp->w_match_head;
0e73038
+ 
0e73038
+     while (cur != NULL && cur->id != id)
0e73038
+ 	cur = cur->next;
0e73038
+     return cur;
0e73038
  }
0e73038
  #endif
0e73038
*** ../vim-7.1.039/src/version.c	Wed Jul 25 22:55:22 2007
0e73038
--- src/version.c	Thu Jul 26 22:50:54 2007
0e73038
***************
0e73038
*** 668,669 ****
0e73038
--- 668,671 ----
0e73038
  {   /* Add new patch number below this line */
0e73038
+ /**/
0e73038
+     40,
0e73038
  /**/
0e73038
0e73038
-- 
0e73038
It is hard to understand how a cemetery raised its burial
0e73038
cost and blamed it on the cost of living.
0e73038
0e73038
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
0e73038
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
0e73038
\\\        download, build and distribute -- http://www.A-A-P.org        ///
0e73038
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///