On Mi, 05 Nov 2014, Bram Moolenaar wrote:

> > this problem is not mentioned in the latest todo list. Is that no issue 
> > for your?
> 
> As I already mentioned: It might break some things.
> 
> The flag does apply to "nextgroup", as documented.  That's why it checks
> current_next_flags.
> 
> Also, the rules become too complex, making a difference for a group that
> has a "containedin" argument changes how the white space before it
> matches.  That's not what someone expects.

How about the current patch. This doesn't touch syntax highlighting. 
This is an enhanced version of the old matchadd_conceal patch from 
https://groups.google.com/d/msg/vim_dev/8bKa98GhHdk/VOzIBhd1m8YJ
The difference is, by default matchadd('Conceal', '/pattern/') works as 
is, but you can add a special dictionary that allows to specify a custom 
cchar value for that particular concealed match.

So use matchadd('Conceal', ' ', 10, -1, {'conceal' "\u2d1"})
to have spaces highlighted with 'ˑ'

This has the advantage of being backwards compatible, while still 
allowing to fine tune each separate Conceal match and also allows for 
future extensions, so one could theoretically add other values to the 
dictionary.

If we could agree to merge this version, we also do not need the 
space_listchars patch 
(https://groups.google.com/d/msg/vim_dev/dIQHjW1g92s/CtBo6MfNXN4J) as it 
could be achieved by using matching functions.

The patch includes a new test to make sure matchadd and matchpos do work 
as expected, it also tests the getmatches() and setmatches() function as 
well as working correctly together with syntax highlightinG. I have 
tried to test all different things I could imagine.

Best,
Christian
-- 
Gern lesen heißt, die einem im Leben zugeteilten Stunden der
Langeweile gegen solche des Entzückens einzutauschen.
                -- Charles-Louis de Montesquieu

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4371,7 +4371,7 @@ match({expr}, {pat}[, {start}[, {count}]
 		done like 'magic' is set and 'cpoptions' is empty.
 
 					*matchadd()* *E798* *E799* *E801*
-matchadd({group}, {pattern}[, {priority}[, {id}]])
+matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]])
 		Defines a pattern to be highlighted in the current window (a
 		"match").  It will be highlighted with {group}.  Returns an
 		identification number (ID), which can be used to delete the
@@ -4396,9 +4396,18 @@ matchadd({group}, {pattern}[, {priority}
 		message will appear and the match will not be added.  An ID
 		is specified as a positive integer (zero excluded).  IDs 1, 2
 		and 3 are reserved for |:match|, |:2match| and |:3match|,
-		respectively.  If the {id} argument is not specified,
+		respectively.  If the {id} argument is not specified or -1,
 		|matchadd()| automatically chooses a free ID.
 
+		The optional {dict} argmument allows for further custom
+		values. Currently this is used to specify a match specifc
+		conceal character that will be shown for |hl-Conceal|
+		highlighted matches. The dict can have the following members:
+
+			conceal	    Special character to show instead of the
+				    match (only for |hl-Conceal| highlighed
+				    matches, see |:syn-cchar|)
+
 		The number of matches is not limited, as it is the case with
 		the |:match| commands.
 
@@ -4412,7 +4421,7 @@ matchadd({group}, {pattern}[, {priority}
 		available from |getmatches()|.	All matches can be deleted in
 		one operation by |clearmatches()|.
 
-matchaddpos({group}, {pos}[, {priority}[, {id}]])		*matchaddpos()*
+matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]])		*matchaddpos()*
 		Same as |matchadd()|, but requires a list of positions {pos}
 		instead of a pattern. This command is faster than |matchadd()|
 		because it does not require to handle regular expressions and
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -8191,8 +8191,8 @@ static struct fst
     {"maparg",		1, 4, f_maparg},
     {"mapcheck",	1, 3, f_mapcheck},
     {"match",		2, 4, f_match},
-    {"matchadd",	2, 4, f_matchadd},
-    {"matchaddpos",	2, 4, f_matchaddpos},
+    {"matchadd",	2, 5, f_matchadd},
+    {"matchaddpos",	2, 5, f_matchaddpos},
     {"matcharg",	1, 1, f_matcharg},
     {"matchdelete",	1, 1, f_matchdelete},
     {"matchend",	2, 4, f_matchend},
@@ -11983,6 +11983,14 @@ f_getmatches(argvars, rettv)
 	    dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
 	    dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
 	    dict_add_nr_str(dict, "id", (long)cur->id, NULL);
+#ifdef FEAT_CONCEAL
+	    if (cur->cchar)
+	    {
+		char_u buf[NUMBUFLEN];
+		buf[(*mb_char2bytes)((int)cur->cchar, buf)] = NUL;
+		dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf);
+	    }
+#endif
 	    list_append_dict(rettv->vval.v_list, dict);
 	    cur = cur->next;
 	}
@@ -14517,6 +14525,7 @@ f_matchadd(argvars, rettv)
     int		prio = 10;	/* default priority */
     int		id = -1;
     int		error = FALSE;
+    char_u	*cchar = NULL;
 
     rettv->vval.v_number = -1;
 
@@ -14526,7 +14535,19 @@ f_matchadd(argvars, rettv)
     {
 	prio = get_tv_number_chk(&argvars[2], &error);
 	if (argvars[3].v_type != VAR_UNKNOWN)
+	{
 	    id = get_tv_number_chk(&argvars[3], &error);
+	    if (argvars[4].v_type != VAR_UNKNOWN)
+	    {
+		if (argvars[4].v_type != VAR_DICT)
+		{
+		    EMSG(_(e_dictreq));
+		    return;
+		}
+		else if (dict_find(argvars[4].vval.v_dict, (char_u *)"conceal", -1) != NULL)
+		    cchar = get_dict_string(argvars[4].vval.v_dict, (char_u *)"conceal", FALSE);
+	    }
+	}
     }
     if (error == TRUE)
 	return;
@@ -14536,7 +14557,7 @@ f_matchadd(argvars, rettv)
 	return;
     }
 
-    rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL);
+    rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL, cchar);
 #endif
 }
 
@@ -14555,6 +14576,7 @@ f_matchaddpos(argvars, rettv)
     int		id = -1;
     int		error = FALSE;
     list_T	*l;
+    char_u	*cchar = NULL;
 
     rettv->vval.v_number = -1;
 
@@ -14575,7 +14597,19 @@ f_matchaddpos(argvars, rettv)
     {
 	prio = get_tv_number_chk(&argvars[2], &error);
 	if (argvars[3].v_type != VAR_UNKNOWN)
+	{
 	    id = get_tv_number_chk(&argvars[3], &error);
+	    if (argvars[4].v_type != VAR_UNKNOWN)
+	    {
+		if (argvars[4].v_type != VAR_DICT)
+		{
+		    EMSG(_(e_dictreq));
+		    return;
+		}
+		else if (dict_find(argvars[4].vval.v_dict, (char_u *)"conceal", -1) != NULL)
+		    cchar = get_dict_string(argvars[4].vval.v_dict, (char_u *)"conceal", FALSE);
+	    }
+	}
     }
     if (error == TRUE)
 	return;
@@ -14587,7 +14621,7 @@ f_matchaddpos(argvars, rettv)
 	return;
     }
 
-    rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l);
+    rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l, cchar);
 #endif
 }
 
@@ -17090,7 +17124,9 @@ f_setmatches(argvars, rettv)
 	    match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
 		    get_dict_string(d, (char_u *)"pattern", FALSE),
 		    (int)get_dict_number(d, (char_u *)"priority"),
-		    (int)get_dict_number(d, (char_u *)"id"), NULL);
+		    (int)get_dict_number(d, (char_u *)"id"), NULL,
+		    (dict_find(d, (char_u *)"conceal", -1) != NULL ?
+		     get_dict_string(d, (char_u *)"conceal", FALSE) : NULL));
 	    li = li->li_next;
 	}
 	rettv->vval.v_number = 0;
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -12049,7 +12049,7 @@ ex_match(eap)
 
 	    c = *end;
 	    *end = NUL;
-	    match_add(curwin, g, p + 1, 10, id, NULL);
+	    match_add(curwin, g, p + 1, 10, id, NULL, NULL);
 	    vim_free(g);
 	    *end = c;
 	}
diff --git a/src/proto/window.pro b/src/proto/window.pro
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -76,7 +76,7 @@ void restore_win __ARGS((win_T *save_cur
 void switch_buffer __ARGS((buf_T **save_curbuf, buf_T *buf));
 void restore_buffer __ARGS((buf_T *save_curbuf));
 int win_hasvertsplit __ARGS((void));
-int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T *pos_list));
+int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T *pos_list, char_u *cchar));
 int match_delete __ARGS((win_T *wp, int id, int perr));
 void clear_matches __ARGS((win_T *wp));
 matchitem_T *get_match __ARGS((win_T *wp, int id));
diff --git a/src/screen.c b/src/screen.c
--- a/src/screen.c
+++ b/src/screen.c
@@ -3025,6 +3025,8 @@ win_line(wp, lnum, startrow, endrow, noc
 					   wrapping */
     int		vcol_off	= 0;	/* offset for concealed characters */
     int		did_wcol	= FALSE;
+    int		match_conc	= FALSE; /* cchar for match functions */
+    int		has_match_conc  = FALSE; /* match wants to conceal */
     int		old_boguscols   = 0;
 # define VCOL_HLC (vcol - vcol_off)
 # define FIX_FOR_BOGUSCOLS \
@@ -3558,6 +3560,9 @@ win_line(wp, lnum, startrow, endrow, noc
      */
     for (;;)
     {
+#ifdef FEAT_CONCEAL
+	has_match_conc = FALSE;
+#endif
 	/* Skip this quickly when working on the text. */
 	if (draw_state != WL_LINE)
 	{
@@ -3901,10 +3906,23 @@ win_line(wp, lnum, startrow, endrow, noc
 				shl->endcol = tmp_col;
 #endif
 			    shl->attr_cur = shl->attr;
+#ifdef FEAT_CONCEAL
+			    if (cur != NULL &&
+				    syn_name2id((char_u *) "Conceal") == cur->hlg_id)
+			    {
+				has_match_conc = TRUE;
+				match_conc = cur->cchar;
+			    }
+			    else
+				has_match_conc = match_conc = FALSE;
+#endif
 			}
 			else if (v == (long)shl->endcol)
 			{
 			    shl->attr_cur = 0;
+#ifdef FEAT_CONCEAL
+			    prev_syntax_id = 0;
+#endif
 			    next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
 			    pos_inprogress = cur == NULL || cur->pos.cur == 0
 							      ? FALSE : TRUE;
@@ -4836,19 +4854,21 @@ win_line(wp, lnum, startrow, endrow, noc
 #ifdef FEAT_CONCEAL
 	    if (   wp->w_p_cole > 0
 		&& (wp != curwin || lnum != wp->w_cursor.lnum ||
-						      conceal_cursor_line(wp))
-		&& (syntax_flags & HL_CONCEAL) != 0
+							conceal_cursor_line(wp) )
+		&& ( (syntax_flags & HL_CONCEAL) != 0 || has_match_conc)
 		&& !(lnum_in_visual_area
 				    && vim_strchr(wp->w_p_cocu, 'v') == NULL))
 	    {
 		char_attr = conceal_attr;
 		if (prev_syntax_id != syntax_seqnr
-			&& (syn_get_sub_char() != NUL || wp->w_p_cole == 1)
+			&& (syn_get_sub_char() != NUL || match_conc || wp->w_p_cole == 1)
 			&& wp->w_p_cole != 3)
 		{
 		    /* First time at this concealed item: display one
 		     * character. */
-		    if (syn_get_sub_char() != NUL)
+		    if (match_conc)
+			c = match_conc;
+		    else if (syn_get_sub_char() != NUL)
 			c = syn_get_sub_char();
 		    else if (lcs_conceal != NUL)
 			c = lcs_conceal;
diff --git a/src/structs.h b/src/structs.h
--- a/src/structs.h
+++ b/src/structs.h
@@ -2014,6 +2014,9 @@ struct matchitem
     regmmatch_T	match;	    /* regexp program for pattern */
     posmatch_T	pos;	    /* position matches */
     match_T	hl;	    /* struct for doing the actual highlighting */
+#ifdef FEAT_CONCEAL
+    int		cchar;	    /* cchar for Conceal highlighting */
+#endif
 };
 
 /*
diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak
--- a/src/testdir/Make_amiga.mak
+++ b/src/testdir/Make_amiga.mak
@@ -49,6 +49,7 @@ SCRIPTS = test1.out test3.out test4.out 
 		test_listlbr_utf8.out \
 		test_mapping.out \
 		test_marks.out \
+		test_match_conceal.out \
 		test_nested_function.out \
 		test_options.out \
 		test_qf_title.out \
@@ -190,6 +191,7 @@ test_listlbr.out: test_listlbr.in
 test_listlbr_utf8.out: test_listlbr_utf8.in
 test_mapping.out: test_mapping.in
 test_marks.out: test_marks.in
+test_match_conceal.out: test_match_conceal.in
 test_nested_function.out: test_nested_function.in
 test_options.out: test_options.in
 test_qf_title.out: test_qf_title.in
diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak
--- a/src/testdir/Make_dos.mak
+++ b/src/testdir/Make_dos.mak
@@ -48,6 +48,7 @@ SCRIPTS =	test3.out test4.out test5.out 
 		test_listlbr_utf8.out \
 		test_mapping.out \
 		test_marks.out \
+		test_match_conceal.out \
 		test_nested_function.out \
 		test_options.out \
 		test_qf_title.out \
diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak
--- a/src/testdir/Make_ming.mak
+++ b/src/testdir/Make_ming.mak
@@ -70,6 +70,7 @@ SCRIPTS =	test3.out test4.out test5.out 
 		test_listlbr_utf8.out \
 		test_mapping.out \
 		test_marks.out \
+		test_match_conceal.out \
 		test_nested_function.out \
 		test_options.out \
 		test_qf_title.out \
diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak
--- a/src/testdir/Make_os2.mak
+++ b/src/testdir/Make_os2.mak
@@ -50,6 +50,7 @@ SCRIPTS = test1.out test3.out test4.out 
 		test_listlbr_utf8.out \
 		test_mapping.out \
 		test_marks.out \
+		test_match_conceal.out \
 		test_nested_function.out \
 		test_options.out \
 		test_qf_title.out \
diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -109,6 +109,7 @@ SCRIPT = test1.out  test2.out  test3.out
 	 test_listlbr_utf8.out \
 	 test_mapping.out \
 	 test_marks.out \
+	 test_match_conceal.out \
 	 test_nested_function.out \
 	 test_options.out \
 	 test_qf_title.out \
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -46,6 +46,7 @@ SCRIPTS = test1.out test2.out test3.out 
 		test_listlbr_utf8.out \
 		test_mapping.out \
 		test_marks.out \
+		test_match_conceal.out \
 		test_nested_function.out \
 		test_options.out \
 		test_qf_title.out \
diff --git a/src/testdir/test_match_conceal.in b/src/testdir/test_match_conceal.in
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_match_conceal.in
@@ -0,0 +1,155 @@
+Test for matchadd() and conceal feature
+
+STARTTEST
+:so small.vim
+:if !has("conceal") || &term=='vt100' | e! test.ok | w! test.out | qa! | endif
+:so mbyte.vim
+:if &enc !=? 'utf-8'|:e! test.ok|:w! test.out|qa!|endif
+:10new|:vsp|:vert resize 20
+:put =\"\#\ This\ is\ a\ Test\"
+:norm! mazt
+:fu! ScreenChar(width, lines)
+:	let c=''
+:	for j in range(1,a:lines)
+:	    for i in range(1,a:width)
+:	    	let c.=nr2char(screenchar(j, i))
+:	    endfor
+:           let c.="\n"
+:	endfor
+:	return c
+:endfu
+:fu! ScreenAttr(line, pos, eval)
+:       let g:attr=[]
+:       for col in a:pos
+:	    call add(g:attr, screenattr(a:line,col))
+:	endfor
+:       let str=substitute(a:eval, '\d\+', 'g:attr[&]', 'g')
+:	if eval(str)
+:	    :let g:attr_test="OK: ". str
+:	else
+:	    :let g:attr_test="FAILED: ".str
+:	    :let g:attr_test.="\n". join(g:attr, ' ')
+:	    :let g:attr_test.="\n TERM: ". &term
+:	endif
+:endfu
+:fu! DoRecordScreen()
+:	wincmd l
+:	$put =printf(\"\n%s\", g:test)
+:	$put =g:line
+:       $put =g:attr_test
+:	wincmd p
+:endfu
+:let g:test ="Test 1: simple addmatch()"
+:call matchadd('Conceal', '\%2l ')
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:
+:let g:test ="Test 2: simple addmatch() and conceal (should be: #XThisXisXaXTest)"
+:norm! 'azt
+:call clearmatches()
+:syntax on
+:set concealcursor=n conceallevel=1
+:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:
+:let g:test ="Test 3: addmatch() and conceallevel=3 (should be: #ThisisaTest)"
+:norm! 'azt
+:set conceallevel=3
+:call clearmatches()
+:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0==1 && 1==2 && 1==3 && 1==4 && 0!=5")
+:call DoRecordScreen()
+:
+:let g:test ="Test 4: more match() (should be: #Thisisa Test)"
+:norm! 'azt
+:call matchadd('ErrorMsg', '\%2l Test', 20, -1, {'conceal': 'X'})
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0==1 && 1==2 && 0!=3 && 3==4 && 0!=5 && 3!=5")
+:call DoRecordScreen()
+:
+:let g:test ="Test 5/1: default conceal char (should be: # This is a Test)"
+:norm! 'azt
+:call clearmatches()
+:set conceallevel=1
+:call matchadd('Conceal', '\%2l ', 10, -1, {})
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:let g:test ="Test 5/2: default conceal char (should be: #+This+is+a+Test)"
+:norm! 'azt
+:set listchars=conceal:+
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:set listchars&vim
+:
+:let g:test ="Test 6/1: syn and match conceal (should be: #ZThisZisZaZTest)"
+:norm! 'azt
+:call clearmatches()
+:set conceallevel=1
+:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
+:syn match MyConceal /\%2l / conceal containedin=ALL cchar=*
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:let g:test ="Test 6/2: syn and match conceal (should be: #*This*is*a*Test)"
+:norm! 'azt
+:call clearmatches()
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:
+:let g:test ="Test 7/1: clear matches"
+:norm! 'azt
+:syn on
+:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
+:let a=getmatches()
+:call clearmatches()
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0==1 && 0==2 && 0==3 && 0==4 && 0==5")
+:call DoRecordScreen()
+:$put =a
+:call setmatches(a)
+:norm! 'azt
+:let g:test ="Test 7/2: reset match using setmatches()"
+:norm! 'azt
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:
+:let g:test ="Test 8: using matchaddpos() (should be #Pis a Test"
+:norm! 'azt
+:call clearmatches()
+:call matchaddpos('Conceal', [[2,2,6]], 10, -1, {'conceal': 'P'})
+:let a=getmatches()
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1!=2 && 0==2 && 0==3 && 0!=4 && 0!=5 && 1!=4 && 4==5")
+:call DoRecordScreen()
+:$put =a
+:
+:let g:test ="Test 9: match using multibyte conceal char (should be: #ˑThisˑisˑaˑTest)"
+:norm! 'azt
+:call clearmatches()
+:call matchadd('Conceal', '\%2l ', 20, -1, {'conceal': "\u02d1"})
+:redraw!
+:let line=ScreenChar(winwidth(0),1)
+:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
+:call DoRecordScreen()
+:
+:"sleep 10
+:%w! test.out
+:qa!
+ENDTEST
+dummy text
diff --git a/src/testdir/test_match_conceal.ok b/src/testdir/test_match_conceal.ok
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_match_conceal.ok
@@ -0,0 +1,52 @@
+
+# This is a Test
+
+Test 1: simple addmatch()
+# This is a Test    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+
+Test 2: simple addmatch() and conceal (should be: #XThisXisXaXTest)
+#XThisXisXaXTest    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+
+Test 3: addmatch() and conceallevel=3 (should be: #ThisisaTest)
+#ThisisaTest        
+OK: g:attr[0]==g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]!=g:attr[5]
+
+Test 4: more match() (should be: #Thisisa Test)
+#Thisisa Test       
+OK: g:attr[0]==g:attr[1] && g:attr[1]==g:attr[2] && g:attr[0]!=g:attr[3] && g:attr[3]==g:attr[4] && g:attr[0]!=g:attr[5] && g:attr[3]!=g:attr[5]
+
+Test 5/1: default conceal char (should be: # This is a Test)
+# This is a Test    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+
+Test 5/2: default conceal char (should be: #+This+is+a+Test)
+#+This+is+a+Test    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+
+Test 6/1: syn and match conceal (should be: #ZThisZisZaZTest)
+#ZThisZisZaZTest    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+
+Test 6/2: syn and match conceal (should be: #*This*is*a*Test)
+#*This*is*a*Test    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+
+Test 7/1: clear matches
+# This is a Test    
+OK: g:attr[0]==g:attr[1] && g:attr[0]==g:attr[2] && g:attr[0]==g:attr[3] && g:attr[0]==g:attr[4] && g:attr[0]==g:attr[5]
+{'group': 'Conceal', 'pattern': '\%2l ', 'priority': 10, 'id': 10, 'conceal': 'Z'}
+
+Test 7/2: reset match using setmatches()
+#ZThisZisZaZTest    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+
+Test 8: using matchaddpos() (should be #Pis a Test
+#Pis a Test         
+OK: g:attr[0]!=g:attr[1] && g:attr[1]!=g:attr[2] && g:attr[0]==g:attr[2] && g:attr[0]==g:attr[3] && g:attr[0]!=g:attr[4] && g:attr[0]!=g:attr[5] && g:attr[1]!=g:attr[4] && g:attr[4]==g:attr[5]
+{'group': 'Conceal', 'id': 11, 'priority': 10, 'pos1': [2, 2, 6], 'conceal': 'P'}
+
+Test 9: match using multibyte conceal char (should be: #ˑThisˑisˑaˑTest)
+#ˑThisˑisˑaˑTest    
+OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
diff --git a/src/window.c b/src/window.c
--- a/src/window.c
+++ b/src/window.c
@@ -6924,13 +6924,14 @@ win_hasvertsplit()
  * Return ID of added match, -1 on failure.
  */
     int
-match_add(wp, grp, pat, prio, id, pos_list)
+match_add(wp, grp, pat, prio, id, pos_list, cchar)
     win_T	*wp;
     char_u	*grp;
     char_u	*pat;
     int		prio;
     int		id;
     list_T	*pos_list;
+    char_u      *cchar;
 {
     matchitem_T	*cur;
     matchitem_T	*prev;
@@ -6990,6 +6991,11 @@ match_add(wp, grp, pat, prio, id, pos_li
     m->match.regprog = regprog;
     m->match.rmm_ic = FALSE;
     m->match.rmm_maxcol = 0;
+#ifdef FEAT_CONCEAL
+    m->cchar = 0;
+    if (cchar != NULL)
+	m->cchar = (*mb_ptr2char)(cchar);
+#endif
 
     /* Set up position matches */
     if (pos_list != NULL)

Raspunde prin e-mail lui