summaryrefslogtreecommitdiff
path: root/src/syntax.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax.c')
-rw-r--r--src/syntax.c920
1 files changed, 552 insertions, 368 deletions
diff --git a/src/syntax.c b/src/syntax.c
index 961348290..c19c5d964 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -140,7 +140,10 @@ typedef struct syn_pattern
{
char sp_type; /* see SPTYPE_ defines below */
char sp_syncing; /* this item used for syncing */
- short sp_flags; /* see HL_ defines below */
+ int sp_flags; /* see HL_ defines below */
+#ifdef FEAT_CONCEAL
+ int sp_char; /* conceal substitute character */
+#endif
struct sp_syn sp_syn; /* struct passed to in_id_list() */
short sp_syn_match_id; /* highlight group ID of pattern */
char_u *sp_pattern; /* regexp to match, pattern */
@@ -166,25 +169,6 @@ typedef struct syn_pattern
#define SPTYPE_END 3 /* match a regexp, end of item */
#define SPTYPE_SKIP 4 /* match a regexp, skip within item */
-#define HL_CONTAINED 0x01 /* not used on toplevel */
-#define HL_TRANSP 0x02 /* has no highlighting */
-#define HL_ONELINE 0x04 /* match within one line only */
-#define HL_HAS_EOL 0x08 /* end pattern that matches with $ */
-#define HL_SYNC_HERE 0x10 /* sync point after this item (syncing only) */
-#define HL_SYNC_THERE 0x20 /* sync point at current line (syncing only) */
-#define HL_MATCH 0x40 /* use match ID instead of item ID */
-#define HL_SKIPNL 0x80 /* nextgroup can skip newlines */
-#define HL_SKIPWHITE 0x100 /* nextgroup can skip white space */
-#define HL_SKIPEMPTY 0x200 /* nextgroup can skip empty lines */
-#define HL_KEEPEND 0x400 /* end match always kept */
-#define HL_EXCLUDENL 0x800 /* exclude NL from match */
-#define HL_DISPLAY 0x1000 /* only used for displaying, not syncing */
-#define HL_FOLD 0x2000 /* define fold */
-#define HL_EXTEND 0x4000 /* ignore a keepend */
-/* These don't fit in a short, thus can't be used for syntax items, only for
- * si_flags and bs_flags. */
-#define HL_MATCHCONT 0x8000 /* match continued from previous line */
-#define HL_TRANS_CONT 0x10000L /* transparent item without contains arg */
#define SYN_ITEMS(buf) ((synpat_T *)((buf)->b_syn_patterns.ga_data))
@@ -208,6 +192,10 @@ static int current_attr = 0; /* attr of current syntax word */
static int current_id = 0; /* ID of current char for syn_get_id() */
static int current_trans_id = 0; /* idem, transparency removed */
#endif
+#ifdef FEAT_CONCEAL
+static int current_flags = 0;
+static int current_sub_char = 0;
+#endif
typedef struct syn_cluster_S
{
@@ -294,6 +282,9 @@ typedef struct state_item
int si_attr; /* attributes in this state */
long si_flags; /* HL_HAS_EOL flag in this state, and
* HL_SKIP* for si_next_list */
+#ifdef FEAT_CONCEAL
+ int si_char; /* substitution character for conceal */
+#endif
short *si_cont_list; /* list of contained groups */
short *si_next_list; /* nextgroup IDs after this item ends */
reg_extmatch_T *si_extmatch; /* \z(...\) matches from start
@@ -351,6 +342,7 @@ static reg_extmatch_T *next_match_extmatch = NULL;
*/
static win_T *syn_win; /* current window for highlighting */
static buf_T *syn_buf; /* current buffer for highlighting */
+static synblock_T *syn_block; /* current buffer for highlighting */
static linenr_T current_lnum = 0; /* lnum of current state */
static colnr_T current_col = 0; /* column of current state */
static int current_state_stored = 0; /* TRUE if stored current state
@@ -370,7 +362,7 @@ static void syn_start_line __ARGS((void));
static void syn_update_ends __ARGS((int startofline));
static void syn_stack_alloc __ARGS((void));
static int syn_stack_cleanup __ARGS((void));
-static void syn_stack_free_entry __ARGS((buf_T *buf, synstate_T *p));
+static void syn_stack_free_entry __ARGS((synblock_T *block, synstate_T *p));
static synstate_T *syn_stack_find_entry __ARGS((linenr_T lnum));
static synstate_T *store_current_state __ARGS((void));
static void load_current_state __ARGS((synstate_T *from));
@@ -390,6 +382,7 @@ static int in_id_list __ARGS((stateitem_T *item, short *cont_list, struct sp_syn
static int push_current_state __ARGS((int idx));
static void pop_current_state __ARGS((void));
+static void syn_stack_apply_changes_block __ARGS((synblock_T *block, buf_T *buf));
static void find_endpos __ARGS((int idx, lpos_T *startpos, lpos_T *m_endpos, lpos_T *hl_endpos, long *flagsp, lpos_T *end_endpos, int *end_idx, reg_extmatch_T *start_ext));
static void clear_syn_state __ARGS((synstate_T *p));
static void clear_current_state __ARGS((void));
@@ -400,14 +393,15 @@ static void syn_add_end_off __ARGS((lpos_T *result, regmmatch_T *regmatch, synpa
static void syn_add_start_off __ARGS((lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra));
static char_u *syn_getcurline __ARGS((void));
static int syn_regexec __ARGS((regmmatch_T *rmp, linenr_T lnum, colnr_T col));
-static int check_keyword_id __ARGS((char_u *line, int startcol, int *endcol, long *flags, short **next_list, stateitem_T *cur_si));
+static int check_keyword_id __ARGS((char_u *line, int startcol, int *endcol, long *flags, short **next_list, stateitem_T *cur_si, int *ccharp));
static void syn_cmd_case __ARGS((exarg_T *eap, int syncing));
static void syn_cmd_spell __ARGS((exarg_T *eap, int syncing));
static void syntax_sync_clear __ARGS((void));
-static void syn_remove_pattern __ARGS((buf_T *buf, int idx));
-static void syn_clear_pattern __ARGS((buf_T *buf, int i));
-static void syn_clear_cluster __ARGS((buf_T *buf, int i));
+static void syn_remove_pattern __ARGS((synblock_T *block, int idx));
+static void syn_clear_pattern __ARGS((synblock_T *block, int i));
+static void syn_clear_cluster __ARGS((synblock_T *block, int i));
static void syn_cmd_clear __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_conceal __ARGS((exarg_T *eap, int syncing));
static void syn_clear_one __ARGS((int id, int syncing));
static void syn_cmd_on __ARGS((exarg_T *eap, int syncing));
static void syn_cmd_enable __ARGS((exarg_T *eap, int syncing));
@@ -418,6 +412,7 @@ static void syn_cmd_onoff __ARGS((exarg_T *eap, char *name));
static void syn_cmd_list __ARGS((exarg_T *eap, int syncing));
static void syn_lines_msg __ARGS((void));
static void syn_match_msg __ARGS((void));
+static void syn_stack_free_block __ARGS((synblock_T *block));
static void syn_list_one __ARGS((int id, int syncing, int link_only));
static void syn_list_cluster __ARGS((int id));
static void put_id_list __ARGS((char_u *name, short *list, int attr));
@@ -425,9 +420,9 @@ static void put_pattern __ARGS((char *s, int c, synpat_T *spp, int attr));
static int syn_list_keywords __ARGS((int id, hashtab_T *ht, int did_header, int attr));
static void syn_clear_keyword __ARGS((int id, hashtab_T *ht));
static void clear_keywtab __ARGS((hashtab_T *ht));
-static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list));
+static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list, int conceal_char));
static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end));
-static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt));
+static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt, int *conceal_char));
static void syn_cmd_include __ARGS((exarg_T *eap, int syncing));
static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing));
static void syn_cmd_match __ARGS((exarg_T *eap, int syncing));
@@ -475,10 +470,11 @@ syntax_start(wp, lnum)
* Also do this when a change was made, the current state may be invalid
* then.
*/
- if (syn_buf != wp->w_buffer || changedtick != syn_buf->b_changedtick)
+ if (syn_block != wp->w_s || changedtick != syn_buf->b_changedtick)
{
invalidate_current_state();
syn_buf = wp->w_buffer;
+ syn_block = wp->w_s;
}
changedtick = syn_buf->b_changedtick;
syn_win = wp;
@@ -487,9 +483,9 @@ syntax_start(wp, lnum)
* Allocate syntax stack when needed.
*/
syn_stack_alloc();
- if (syn_buf->b_sst_array == NULL)
+ if (syn_block->b_sst_array == NULL)
return; /* out of memory */
- syn_buf->b_sst_lasttick = display_tick;
+ syn_block->b_sst_lasttick = display_tick;
/*
* If the state of the end of the previous line is useful, store it.
@@ -520,17 +516,17 @@ syntax_start(wp, lnum)
* Try to synchronize from a saved state in b_sst_array[].
* Only do this if lnum is not before and not to far beyond a saved state.
*/
- if (INVALID_STATE(&current_state) && syn_buf->b_sst_array != NULL)
+ if (INVALID_STATE(&current_state) && syn_block->b_sst_array != NULL)
{
/* Find last valid saved state before start_lnum. */
- for (p = syn_buf->b_sst_first; p != NULL; p = p->sst_next)
+ for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next)
{
if (p->sst_lnum > lnum)
break;
if (p->sst_lnum <= lnum && p->sst_change_lnum == 0)
{
last_valid = p;
- if (p->sst_lnum >= lnum - syn_buf->b_syn_sync_minlines)
+ if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines)
last_min_valid = p;
}
}
@@ -545,7 +541,7 @@ syntax_start(wp, lnum)
if (INVALID_STATE(&current_state))
{
syn_sync(wp, lnum, last_valid);
- first_stored = current_lnum + syn_buf->b_syn_sync_minlines;
+ first_stored = current_lnum + syn_block->b_syn_sync_minlines;
}
else
first_stored = current_lnum;
@@ -554,10 +550,10 @@ syntax_start(wp, lnum)
* Advance from the sync point or saved state until the current line.
* Save some entries for syncing with later on.
*/
- if (syn_buf->b_sst_len <= Rows)
+ if (syn_block->b_sst_len <= Rows)
dist = 999999;
else
- dist = syn_buf->b_ml.ml_line_count / (syn_buf->b_sst_len - Rows) + 1;
+ dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1;
while (current_lnum < lnum)
{
syn_start_line();
@@ -574,7 +570,7 @@ syntax_start(wp, lnum)
if (prev == NULL)
prev = syn_stack_find_entry(current_lnum - 1);
if (prev == NULL)
- sp = syn_buf->b_sst_first;
+ sp = syn_block->b_sst_first;
else
sp = prev;
while (sp != NULL && sp->sst_lnum < current_lnum)
@@ -706,19 +702,19 @@ syn_sync(wp, start_lnum, last_valid)
* where N is minlines * 1.5, or minlines * 2 if minlines is small.
* Watch out for overflow when minlines is MAXLNUM.
*/
- if (syn_buf->b_syn_sync_minlines > start_lnum)
+ if (syn_block->b_syn_sync_minlines > start_lnum)
start_lnum = 1;
else
{
- if (syn_buf->b_syn_sync_minlines == 1)
+ if (syn_block->b_syn_sync_minlines == 1)
lnum = 1;
- else if (syn_buf->b_syn_sync_minlines < 10)
- lnum = syn_buf->b_syn_sync_minlines * 2;
+ else if (syn_block->b_syn_sync_minlines < 10)
+ lnum = syn_block->b_syn_sync_minlines * 2;
else
- lnum = syn_buf->b_syn_sync_minlines * 3 / 2;
- if (syn_buf->b_syn_sync_maxlines != 0
- && lnum > syn_buf->b_syn_sync_maxlines)
- lnum = syn_buf->b_syn_sync_maxlines;
+ lnum = syn_block->b_syn_sync_minlines * 3 / 2;
+ if (syn_block->b_syn_sync_maxlines != 0
+ && lnum > syn_block->b_syn_sync_maxlines)
+ lnum = syn_block->b_syn_sync_maxlines;
if (lnum >= start_lnum)
start_lnum = 1;
else
@@ -729,7 +725,7 @@ syn_sync(wp, start_lnum, last_valid)
/*
* 1. Search backwards for the end of a C-style comment.
*/
- if (syn_buf->b_syn_sync_flags & SF_CCOMMENT)
+ if (syn_block->b_syn_sync_flags & SF_CCOMMENT)
{
/* Need to make syn_buf the current buffer for a moment, to be able to
* use find_start_comment(). */
@@ -759,11 +755,12 @@ syn_sync(wp, start_lnum, last_valid)
* defines the comment.
* Restrict the search for the end of a comment to b_syn_sync_maxlines.
*/
- if (find_start_comment((int)syn_buf->b_syn_sync_maxlines) != NULL)
+ if (find_start_comment((int)syn_block->b_syn_sync_maxlines) != NULL)
{
- for (idx = syn_buf->b_syn_patterns.ga_len; --idx >= 0; )
- if (SYN_ITEMS(syn_buf)[idx].sp_syn.id == syn_buf->b_syn_sync_id
- && SYN_ITEMS(syn_buf)[idx].sp_type == SPTYPE_START)
+ for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; )
+ if (SYN_ITEMS(syn_block)[idx].sp_syn.id
+ == syn_block->b_syn_sync_id
+ && SYN_ITEMS(syn_block)[idx].sp_type == SPTYPE_START)
{
validate_current_state();
if (push_current_state(idx) == OK)
@@ -781,11 +778,11 @@ syn_sync(wp, start_lnum, last_valid)
/*
* 2. Search backwards for given sync patterns.
*/
- else if (syn_buf->b_syn_sync_flags & SF_MATCH)
+ else if (syn_block->b_syn_sync_flags & SF_MATCH)
{
- if (syn_buf->b_syn_sync_maxlines != 0
- && start_lnum > syn_buf->b_syn_sync_maxlines)
- break_lnum = start_lnum - syn_buf->b_syn_sync_maxlines;
+ if (syn_block->b_syn_sync_maxlines != 0
+ && start_lnum > syn_block->b_syn_sync_maxlines)
+ break_lnum = start_lnum - syn_block->b_syn_sync_maxlines;
else
break_lnum = 0;
@@ -849,7 +846,7 @@ syn_sync(wp, start_lnum, last_valid)
}
else
{
- spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
+ spp = &(SYN_ITEMS(syn_block)[cur_si->si_idx]);
found_flags = spp->sp_flags;
found_match_idx = spp->sp_sync_idx;
}
@@ -952,10 +949,10 @@ syn_match_linecont(lnum)
{
regmmatch_T regmatch;
- if (syn_buf->b_syn_linecont_prog != NULL)
+ if (syn_block->b_syn_linecont_prog != NULL)
{
- regmatch.rmm_ic = syn_buf->b_syn_linecont_ic;
- regmatch.regprog = syn_buf->b_syn_linecont_prog;
+ regmatch.rmm_ic = syn_block->b_syn_linecont_ic;
+ regmatch.regprog = syn_block->b_syn_linecont_prog;
return syn_regexec(&regmatch, lnum, (colnr_T)0);
}
return FALSE;
@@ -1002,7 +999,7 @@ syn_update_ends(startofline)
{
cur_si = &CUR_STATE(i);
if (cur_si->si_idx >= 0
- && (SYN_ITEMS(syn_buf)[cur_si->si_idx]).sp_type
+ && (SYN_ITEMS(syn_block)[cur_si->si_idx]).sp_type
== SPTYPE_MATCH
&& cur_si->si_m_endpos.lnum < current_lnum)
{
@@ -1088,30 +1085,39 @@ syn_update_ends(startofline)
* number of entries SST_MAX_ENTRIES, and the distance is computed.
*/
+ static void
+syn_stack_free_block(block)
+ synblock_T *block;
+{
+ synstate_T *p;
+
+ if (block->b_sst_array != NULL)
+ {
+ for (p = block->b_sst_first; p != NULL; p = p->sst_next)
+ clear_syn_state(p);
+ vim_free(block->b_sst_array);
+ block->b_sst_array = NULL;
+ block->b_sst_len = 0;
+ }
+}
/*
* Free b_sst_array[] for buffer "buf".
* Used when syntax items changed to force resyncing everywhere.
*/
void
-syn_stack_free_all(buf)
- buf_T *buf;
+syn_stack_free_all(block)
+ synblock_T *block;
{
- synstate_T *p;
win_T *wp;
- if (buf->b_sst_array != NULL)
- {
- for (p = buf->b_sst_first; p != NULL; p = p->sst_next)
- clear_syn_state(p);
- vim_free(buf->b_sst_array);
- buf->b_sst_array = NULL;
- buf->b_sst_len = 0;
- }
+ syn_stack_free_block(block);
+
+
#ifdef FEAT_FOLDING
/* When using "syntax" fold method, must update all folds. */
FOR_ALL_WINDOWS(wp)
{
- if (wp->w_buffer == buf && foldmethodIsSyntax(wp))
+ if (wp->w_s == block && foldmethodIsSyntax(wp))
foldUpdateAll(wp);
}
#endif
@@ -1135,7 +1141,7 @@ syn_stack_alloc()
len = SST_MIN_ENTRIES;
else if (len > SST_MAX_ENTRIES)
len = SST_MAX_ENTRIES;
- if (syn_buf->b_sst_len > len * 2 || syn_buf->b_sst_len < len)
+ if (syn_block->b_sst_len > len * 2 || syn_block->b_sst_len < len)
{
/* Allocate 50% too much, to avoid reallocating too often. */
len = syn_buf->b_ml.ml_line_count;
@@ -1145,15 +1151,15 @@ syn_stack_alloc()
else if (len > SST_MAX_ENTRIES)
len = SST_MAX_ENTRIES;
- if (syn_buf->b_sst_array != NULL)
+ if (syn_block->b_sst_array != NULL)
{
/* When shrinking the array, cleanup the existing stack.
* Make sure that all valid entries fit in the new array. */
- while (syn_buf->b_sst_len - syn_buf->b_sst_freecount + 2 > len
+ while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len
&& syn_stack_cleanup())
;
- if (len < syn_buf->b_sst_len - syn_buf->b_sst_freecount + 2)
- len = syn_buf->b_sst_len - syn_buf->b_sst_freecount + 2;
+ if (len < syn_block->b_sst_len - syn_block->b_sst_freecount + 2)
+ len = syn_block->b_sst_len - syn_block->b_sst_freecount + 2;
}
sstp = (synstate_T *)alloc_clear((unsigned)(len * sizeof(synstate_T)));
@@ -1161,10 +1167,10 @@ syn_stack_alloc()
return;
to = sstp - 1;
- if (syn_buf->b_sst_array != NULL)
+ if (syn_block->b_sst_array != NULL)
{
/* Move the states from the old array to the new one. */
- for (from = syn_buf->b_sst_first; from != NULL;
+ for (from = syn_block->b_sst_first; from != NULL;
from = from->sst_next)
{
++to;
@@ -1175,24 +1181,24 @@ syn_stack_alloc()
if (to != sstp - 1)
{
to->sst_next = NULL;
- syn_buf->b_sst_first = sstp;
- syn_buf->b_sst_freecount = len - (int)(to - sstp) - 1;
+ syn_block->b_sst_first = sstp;
+ syn_block->b_sst_freecount = len - (int)(to - sstp) - 1;
}
else
{
- syn_buf->b_sst_first = NULL;
- syn_buf->b_sst_freecount = len;
+ syn_block->b_sst_first = NULL;
+ syn_block->b_sst_freecount = len;
}
/* Create the list of free entries. */
- syn_buf->b_sst_firstfree = to + 1;
+ syn_block->b_sst_firstfree = to + 1;
while (++to < sstp + len)
to->sst_next = to + 1;
(sstp + len - 1)->sst_next = NULL;
- vim_free(syn_buf->b_sst_array);
- syn_buf->b_sst_array = sstp;
- syn_buf->b_sst_len = len;
+ vim_free(syn_block->b_sst_array);
+ syn_block->b_sst_array = sstp;
+ syn_block->b_sst_len = len;
}
}
@@ -1206,16 +1212,32 @@ syn_stack_alloc()
syn_stack_apply_changes(buf)
buf_T *buf;
{
+ win_T *wp;
+
+ syn_stack_apply_changes_block(&buf->b_s, buf);
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if ((wp->w_buffer == buf) && (wp->w_s != &buf->b_s))
+ syn_stack_apply_changes_block(wp->w_s, buf);
+ }
+}
+
+ static void
+syn_stack_apply_changes_block(block, buf)
+ synblock_T *block;
+ buf_T *buf;
+{
synstate_T *p, *prev, *np;
linenr_T n;
- if (buf->b_sst_array == NULL) /* nothing to do */
+ if (block->b_sst_array == NULL) /* nothing to do */
return;
prev = NULL;
- for (p = buf->b_sst_first; p != NULL; )
+ for (p = block->b_sst_first; p != NULL; )
{
- if (p->sst_lnum + buf->b_syn_sync_linebreaks > buf->b_mod_top)
+ if (p->sst_lnum + block->b_syn_sync_linebreaks > buf->b_mod_top)
{
n = p->sst_lnum + buf->b_mod_xlines;
if (n <= buf->b_mod_bot)
@@ -1223,10 +1245,10 @@ syn_stack_apply_changes(buf)
/* this state is inside the changed area, remove it */
np = p->sst_next;
if (prev == NULL)
- buf->b_sst_first = np;
+ block->b_sst_first = np;
else
prev->sst_next = np;
- syn_stack_free_entry(buf, p);
+ syn_stack_free_entry(block, p);
p = np;
continue;
}
@@ -1264,28 +1286,28 @@ syn_stack_cleanup()
int dist;
int retval = FALSE;
- if (syn_buf->b_sst_array == NULL || syn_buf->b_sst_first == NULL)
+ if (syn_block->b_sst_array == NULL || syn_block->b_sst_first == NULL)
return retval;
/* Compute normal distance between non-displayed entries. */
- if (syn_buf->b_sst_len <= Rows)
+ if (syn_block->b_sst_len <= Rows)
dist = 999999;
else
- dist = syn_buf->b_ml.ml_line_count / (syn_buf->b_sst_len - Rows) + 1;
+ dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1;
/*
* Go through the list to find the "tick" for the oldest entry that can
* be removed. Set "above" when the "tick" for the oldest entry is above
* "b_sst_lasttick" (the display tick wraps around).
*/
- tick = syn_buf->b_sst_lasttick;
+ tick = syn_block->b_sst_lasttick;
above = FALSE;
- prev = syn_buf->b_sst_first;
+ prev = syn_block->b_sst_first;
for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next)
{
if (prev->sst_lnum + dist > p->sst_lnum)
{
- if (p->sst_tick > syn_buf->b_sst_lasttick)
+ if (p->sst_tick > syn_block->b_sst_lasttick)
{
if (!above || p->sst_tick < tick)
tick = p->sst_tick;
@@ -1300,14 +1322,14 @@ syn_stack_cleanup()
* Go through the list to make the entries for the oldest tick at an
* interval of several lines.
*/
- prev = syn_buf->b_sst_first;
+ prev = syn_block->b_sst_first;
for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next)
{
if (p->sst_tick == tick && prev->sst_lnum + dist > p->sst_lnum)
{
/* Move this entry from used list to free list */
prev->sst_next = p->sst_next;
- syn_stack_free_entry(syn_buf, p);
+ syn_stack_free_entry(syn_block, p);
p = prev;
retval = TRUE;
}
@@ -1320,14 +1342,14 @@ syn_stack_cleanup()
* Move the entry into the free list.
*/
static void
-syn_stack_free_entry(buf, p)
- buf_T *buf;
+syn_stack_free_entry(block, p)
+ synblock_T *block;
synstate_T *p;
{
clear_syn_state(p);
- p->sst_next = buf->b_sst_firstfree;
- buf->b_sst_firstfree = p;
- ++buf->b_sst_freecount;
+ p->sst_next = block->b_sst_firstfree;
+ block->b_sst_firstfree = p;
+ ++block->b_sst_freecount;
}
/*
@@ -1341,7 +1363,7 @@ syn_stack_find_entry(lnum)
synstate_T *p, *prev;
prev = NULL;
- for (p = syn_buf->b_sst_first; p != NULL; prev = p, p = p->sst_next)
+ for (p = syn_block->b_sst_first; p != NULL; prev = p, p = p->sst_next)
{
if (p->sst_lnum == lnum)
return p;
@@ -1383,19 +1405,19 @@ store_current_state()
if (sp != NULL)
{
/* find "sp" in the list and remove it */
- if (syn_buf->b_sst_first == sp)
+ if (syn_block->b_sst_first == sp)
/* it's the first entry */
- syn_buf->b_sst_first = sp->sst_next;
+ syn_block->b_sst_first = sp->sst_next;
else
{
/* find the entry just before this one to adjust sst_next */
- for (p = syn_buf->b_sst_first; p != NULL; p = p->sst_next)
+ for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next)
if (p->sst_next == sp)
break;
if (p != NULL) /* just in case */
p->sst_next = sp->sst_next;
}
- syn_stack_free_entry(syn_buf, sp);
+ syn_stack_free_entry(syn_block, sp);
sp = NULL;
}
}
@@ -1405,27 +1427,27 @@ store_current_state()
* Add a new entry
*/
/* If no free items, cleanup the array first. */
- if (syn_buf->b_sst_freecount == 0)
+ if (syn_block->b_sst_freecount == 0)
{
(void)syn_stack_cleanup();
/* "sp" may have been moved to the freelist now */
sp = syn_stack_find_entry(current_lnum);
}
/* Still no free items? Must be a strange problem... */
- if (syn_buf->b_sst_freecount == 0)
+ if (syn_block->b_sst_freecount == 0)
sp = NULL;
else
{
/* Take the first item from the free list and put it in the used
* list, after *sp */
- p = syn_buf->b_sst_firstfree;
- syn_buf->b_sst_firstfree = p->sst_next;
- --syn_buf->b_sst_freecount;
+ p = syn_block->b_sst_firstfree;
+ syn_block->b_sst_firstfree = p->sst_next;
+ --syn_block->b_sst_freecount;
if (sp == NULL)
{
/* Insert in front of the list */
- p->sst_next = syn_buf->b_sst_first;
- syn_buf->b_sst_first = p;
+ p->sst_next = syn_block->b_sst_first;
+ syn_block->b_sst_first = p;
}
else
{
@@ -1502,7 +1524,7 @@ load_current_state(from)
CUR_STATE(i).si_m_lnum = 0;
if (CUR_STATE(i).si_idx >= 0)
CUR_STATE(i).si_next_list =
- (SYN_ITEMS(syn_buf)[CUR_STATE(i).si_idx]).sp_next_list;
+ (SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_next_list;
else
CUR_STATE(i).si_next_list = NULL;
update_si_attr(i);
@@ -1564,7 +1586,7 @@ syn_stack_equal(sp)
if (bsx->matches[j] == NULL
|| six->matches[j] == NULL)
break;
- if ((SYN_ITEMS(syn_buf)[CUR_STATE(i).si_idx]).sp_ic
+ if ((SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_ic
? MB_STRICMP(bsx->matches[j],
six->matches[j]) != 0
: STRCMP(bsx->matches[j], six->matches[j]) != 0)
@@ -1701,7 +1723,7 @@ syn_finish_line(syncing)
*/
cur_si = &CUR_STATE(current_state.ga_len - 1);
if (cur_si->si_idx >= 0
- && (SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_flags
+ && (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
& (HL_SYNC_HERE|HL_SYNC_THERE)))
return TRUE;
@@ -1730,8 +1752,9 @@ syn_finish_line(syncing)
* done.
*/
int
-get_syntax_attr(col, can_spell, keep_state)
+get_syntax_attr(col, p_flags, can_spell, keep_state)
colnr_T col;
+ int *p_flags UNUSED;
int *can_spell;
int keep_state; /* keep state of char at "col" */
{
@@ -1740,12 +1763,12 @@ get_syntax_attr(col, can_spell, keep_state)
if (can_spell != NULL)
/* Default: Only do spelling when there is no @Spell cluster or when
* ":syn spell toplevel" was used. */
- *can_spell = syn_buf->b_syn_spell == SYNSPL_DEFAULT
- ? (syn_buf->b_spell_cluster_id == 0)
- : (syn_buf->b_syn_spell == SYNSPL_TOP);
+ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
+ ? (syn_block->b_spell_cluster_id == 0)
+ : (syn_block->b_syn_spell == SYNSPL_TOP);
/* check for out of memory situation */
- if (syn_buf->b_sst_array == NULL)
+ if (syn_block->b_sst_array == NULL)
return 0;
/* After 'synmaxcol' the attribute is always zero. */
@@ -1773,6 +1796,10 @@ get_syntax_attr(col, can_spell, keep_state)
++current_col;
}
+#ifdef FEAT_CONCEAL
+ if (p_flags != NULL)
+ *p_flags = current_flags;
+#endif
return attr;
}
@@ -1799,6 +1826,7 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
int startcol;
int endcol;
long flags;
+ int cchar;
short *next_list;
int found_match; /* found usable match */
static int try_next_column = FALSE; /* must try in next col */
@@ -1854,8 +1882,8 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
/* Only check for keywords when not syncing and there are some. */
do_keywords = !syncing
- && (syn_buf->b_keywtab.ht_used > 0
- || syn_buf->b_keywtab_ic.ht_used > 0);
+ && (syn_block->b_keywtab.ht_used > 0
+ || syn_block->b_keywtab_ic.ht_used > 0);
/* Init the list of zero-width matches with a nextlist. This is used to
* avoid matching the same item in the same position twice. */
@@ -1884,7 +1912,7 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
else
cur_si = NULL;
- if (syn_buf->b_syn_containedin || cur_si == NULL
+ if (syn_block->b_syn_containedin || cur_si == NULL
|| cur_si->si_cont_list != NULL)
{
/*
@@ -1905,7 +1933,8 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
, syn_buf)))
{
syn_id = check_keyword_id(line, (int)current_col,
- &endcol, &flags, &next_list, cur_si);
+ &endcol, &flags, &next_list, cur_si,
+ &cchar);
if (syn_id != 0)
{
if (push_current_state(KEYWORD_IDX) == OK)
@@ -1921,6 +1950,13 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
cur_si->si_ends = TRUE;
cur_si->si_end_idx = 0;
cur_si->si_flags = flags;
+#ifdef FEAT_CONCEAL
+ cur_si->si_char = cchar;
+ if (current_state.ga_len > 1)
+ cur_si->si_flags |=
+ CUR_STATE(current_state.ga_len - 2).si_flags
+ & HL_CONCEAL;
+#endif
cur_si->si_id = syn_id;
cur_si->si_trans_id = syn_id;
if (flags & HL_TRANSP)
@@ -1953,7 +1989,7 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
/*
* 3. Check for patterns (only if no keyword found).
*/
- if (syn_id == 0 && syn_buf->b_syn_patterns.ga_len)
+ if (syn_id == 0 && syn_block->b_syn_patterns.ga_len)
{
/*
* If we didn't check for a match yet, or we are past it, check
@@ -1969,9 +2005,9 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
*/
next_match_idx = 0; /* no match in this line yet */
next_match_col = MAXCOL;
- for (idx = syn_buf->b_syn_patterns.ga_len; --idx >= 0; )
+ for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; )
{
- spp = &(SYN_ITEMS(syn_buf)[idx]);
+ spp = &(SYN_ITEMS(syn_block)[idx]);
if ( spp->sp_syncing == syncing
&& (displaying || !(spp->sp_flags & HL_DISPLAY))
&& (spp->sp_type == SPTYPE_MATCH
@@ -2147,7 +2183,7 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
/* When a zero-width item matched which has a nextgroup,
* don't push the item but set nextgroup. */
- lspp = &(SYN_ITEMS(syn_buf)[next_match_idx]);
+ lspp = &(SYN_ITEMS(syn_block)[next_match_idx]);
if (next_match_m_endpos.lnum == current_lnum
&& next_match_m_endpos.col == current_col
&& lspp->sp_next_list != NULL)
@@ -2219,6 +2255,9 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
current_id = 0;
current_trans_id = 0;
#endif
+#ifdef FEAT_CONCEAL
+ current_flags = 0;
+#endif
if (cur_si != NULL)
{
#ifndef FEAT_EVAL
@@ -2240,6 +2279,10 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
current_id = sip->si_id;
#endif
current_trans_id = sip->si_trans_id;
+#ifdef FEAT_CONCEAL
+ current_flags = sip->si_flags;
+ current_sub_char = sip->si_char;
+#endif
break;
}
}
@@ -2252,16 +2295,17 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
* set "can_spell" to TRUE if spell checking is supposed to be
* done in the current item.
*/
- if (syn_buf->b_spell_cluster_id == 0)
+ if (syn_block->b_spell_cluster_id == 0)
{
/* There is no @Spell cluster: Do spelling for items without
* @NoSpell cluster. */
- if (syn_buf->b_nospell_cluster_id == 0 || current_trans_id == 0)
- *can_spell = (syn_buf->b_syn_spell != SYNSPL_NOTOP);
+ if (syn_block->b_nospell_cluster_id == 0
+ || current_trans_id == 0)
+ *can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP);
else
{
sps.inc_tag = 0;
- sps.id = syn_buf->b_nospell_cluster_id;
+ sps.id = syn_block->b_nospell_cluster_id;
sps.cont_in_list = NULL;
*can_spell = !in_id_list(sip, sip->si_cont_list, &sps, 0);
}
@@ -2273,17 +2317,17 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
* At the toplevel only spell check when ":syn spell toplevel"
* was used. */
if (current_trans_id == 0)
- *can_spell = (syn_buf->b_syn_spell == SYNSPL_TOP);
+ *can_spell = (syn_block->b_syn_spell == SYNSPL_TOP);
else
{
sps.inc_tag = 0;
- sps.id = syn_buf->b_spell_cluster_id;
+ sps.id = syn_block->b_spell_cluster_id;
sps.cont_in_list = NULL;
*can_spell = in_id_list(sip, sip->si_cont_list, &sps, 0);
- if (syn_buf->b_nospell_cluster_id != 0)
+ if (syn_block->b_nospell_cluster_id != 0)
{
- sps.id = syn_buf->b_nospell_cluster_id;
+ sps.id = syn_block->b_nospell_cluster_id;
if (in_id_list(sip, sip->si_cont_list, &sps, 0))
*can_spell = FALSE;
}
@@ -2315,9 +2359,9 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
else if (can_spell != NULL)
/* Default: Only do spelling when there is no @Spell cluster or when
* ":syn spell toplevel" was used. */
- *can_spell = syn_buf->b_syn_spell == SYNSPL_DEFAULT
- ? (syn_buf->b_spell_cluster_id == 0)
- : (syn_buf->b_syn_spell == SYNSPL_TOP);
+ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
+ ? (syn_block->b_spell_cluster_id == 0)
+ : (syn_block->b_syn_spell == SYNSPL_TOP);
/* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */
if (current_next_list != NULL
@@ -2370,8 +2414,11 @@ push_next_match(cur_si)
stateitem_T *cur_si;
{
synpat_T *spp;
+#ifdef FEAT_CONCEAL
+ int save_flags;
+#endif
- spp = &(SYN_ITEMS(syn_buf)[next_match_idx]);
+ spp = &(SYN_ITEMS(syn_block)[next_match_idx]);
/*
* Push the item in current_state stack;
@@ -2387,6 +2434,12 @@ push_next_match(cur_si)
cur_si->si_m_startcol = current_col;
cur_si->si_m_lnum = current_lnum;
cur_si->si_flags = spp->sp_flags;
+#ifdef FEAT_CONCEAL
+ cur_si->si_char = spp->sp_char;
+ if (current_state.ga_len > 1)
+ cur_si->si_flags |=
+ CUR_STATE(current_state.ga_len - 2).si_flags & HL_CONCEAL;
+#endif
cur_si->si_next_list = spp->sp_next_list;
cur_si->si_extmatch = ref_extmatch(next_match_extmatch);
if (spp->sp_type == SPTYPE_START && !(spp->sp_flags & HL_ONELINE))
@@ -2409,6 +2462,9 @@ push_next_match(cur_si)
check_keepend();
update_si_attr(current_state.ga_len - 1);
+#ifdef FEAT_CONCEAL
+ save_flags = cur_si->si_flags & (HL_CONCEAL | HL_CONCEALENDS);
+#endif
/*
* If the start pattern has another highlight group, push another item
* on the stack for the start pattern.
@@ -2426,6 +2482,11 @@ push_next_match(cur_si)
cur_si->si_ends = TRUE;
cur_si->si_end_idx = 0;
cur_si->si_flags = HL_MATCH;
+#ifdef FEAT_CONCEAL
+ cur_si->si_flags |= save_flags;
+ if (cur_si->si_flags & HL_CONCEALENDS)
+ cur_si->si_flags |= HL_CONCEAL;
+#endif
cur_si->si_next_list = NULL;
check_keepend();
update_si_attr(current_state.ga_len - 1);
@@ -2470,6 +2531,10 @@ check_state_ends()
cur_si->si_m_endpos = cur_si->si_eoe_pos;
cur_si->si_h_endpos = cur_si->si_eoe_pos;
cur_si->si_flags |= HL_MATCH;
+#ifdef FEAT_CONCEAL
+ if (cur_si->si_flags & HL_CONCEALENDS)
+ cur_si->si_flags |= HL_CONCEAL;
+#endif
update_si_attr(current_state.ga_len - 1);
/* what matches next may be different now, clear it */
@@ -2516,7 +2581,7 @@ check_state_ends()
* - "excludenl" is used (HL_HAS_EOL won't be set)
*/
if (cur_si->si_idx >= 0
- && SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_type
+ && SYN_ITEMS(syn_block)[cur_si->si_idx].sp_type
== SPTYPE_START
&& !(cur_si->si_flags & (HL_MATCH | HL_KEEPEND)))
{
@@ -2549,7 +2614,7 @@ update_si_attr(idx)
if (sip->si_idx < 0)
return;
- spp = &(SYN_ITEMS(syn_buf)[sip->si_idx]);
+ spp = &(SYN_ITEMS(syn_block)[sip->si_idx]);
if (sip->si_flags & HL_MATCH)
sip->si_id = spp->sp_syn_match_id;
else
@@ -2689,7 +2754,7 @@ update_si_end(sip, startcol, force)
if (endpos.lnum == 0)
{
/* No end pattern matched. */
- if (SYN_ITEMS(syn_buf)[sip->si_idx].sp_flags & HL_ONELINE)
+ if (SYN_ITEMS(syn_block)[sip->si_idx].sp_flags & HL_ONELINE)
{
/* a "oneline" never continues in the next line */
sip->si_ends = TRUE;
@@ -2791,7 +2856,7 @@ find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
* Can happen with a match that continues to the next line, because it
* contained a region.
*/
- spp = &(SYN_ITEMS(syn_buf)[idx]);
+ spp = &(SYN_ITEMS(syn_block)[idx]);
if (spp->sp_type != SPTYPE_START)
{
*hl_endpos = *startpos;
@@ -2803,7 +2868,7 @@ find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
*/
for (;;)
{
- spp = &(SYN_ITEMS(syn_buf)[idx]);
+ spp = &(SYN_ITEMS(syn_block)[idx]);
if (spp->sp_type != SPTYPE_START)
break;
++idx;
@@ -2833,11 +2898,11 @@ find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
* Find end pattern that matches first after "matchcol".
*/
best_idx = -1;
- for (idx = start_idx; idx < syn_buf->b_syn_patterns.ga_len; ++idx)
+ for (idx = start_idx; idx < syn_block->b_syn_patterns.ga_len; ++idx)
{
int lc_col = matchcol;
- spp = &(SYN_ITEMS(syn_buf)[idx]);
+ spp = &(SYN_ITEMS(syn_block)[idx]);
if (spp->sp_type != SPTYPE_END) /* past last END pattern */
break;
lc_col -= spp->sp_offsets[SPO_LC_OFF];
@@ -2915,7 +2980,7 @@ find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
* Match from start pattern to end pattern.
* Correct for match and highlight offset of end pattern.
*/
- spp = &(SYN_ITEMS(syn_buf)[best_idx]);
+ spp = &(SYN_ITEMS(syn_block)[best_idx]);
syn_add_end_off(m_endpos, &best_regmatch, spp, SPO_ME_OFF, 1);
/* can't end before the start */
if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col)
@@ -3146,13 +3211,14 @@ syn_regexec(rmp, lnum, col)
* Return it's ID if found, 0 otherwise.
*/
static int
-check_keyword_id(line, startcol, endcolp, flagsp, next_listp, cur_si)
+check_keyword_id(line, startcol, endcolp, flagsp, next_listp, cur_si, ccharp)
char_u *line;
int startcol; /* position in line to check for keyword */
int *endcolp; /* return: character after found keyword */
long *flagsp; /* return: flags of matching keyword */
short **next_listp; /* return: next_list of matching keyword */
stateitem_T *cur_si; /* item at the top of the stack */
+ int *ccharp UNUSED; /* conceal substitution char */
{
keyentry_T *kp;
char_u *kwp;
@@ -3193,7 +3259,7 @@ check_keyword_id(line, startcol, endcolp, flagsp, next_listp, cur_si)
*/
for (round = 1; round <= 2; ++round)
{
- ht = round == 1 ? &syn_buf->b_keywtab : &syn_buf->b_keywtab_ic;
+ ht = round == 1 ? &syn_block->b_keywtab : &syn_block->b_keywtab_ic;
if (ht->ht_used == 0)
continue;
if (round == 2) /* ignore case */
@@ -3220,6 +3286,9 @@ check_keyword_id(line, startcol, endcolp, flagsp, next_listp, cur_si)
*endcolp = startcol + kwlen;
*flagsp = kp->flags;
*next_listp = kp->next_list;
+#ifdef FEAT_CONCEAL
+ *ccharp = kp->k_char;
+#endif
return kp->k_syn.id;
}
}
@@ -3228,6 +3297,32 @@ check_keyword_id(line, startcol, endcolp, flagsp, next_listp, cur_si)
}
/*
+ * Handle ":syntax conceal" command.
+ */
+ static void
+syn_cmd_conceal(eap, syncing)
+ exarg_T *eap UNUSED;
+ int syncing UNUSED;
+{
+#ifdef FEAT_CONCEAL
+ char_u *arg = eap->arg;
+ char_u *next;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ return;
+
+ next = skiptowhite(arg);
+ if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
+ curwin->w_s->b_syn_conceal = TRUE;
+ else if (STRNICMP(arg, "off", 3) == 0 && next - arg == 3)
+ curwin->w_s->b_syn_conceal = FALSE;
+ else
+ EMSG2(_("E390: Illegal argument: %s"), arg);
+#endif
+}
+
+/*
* Handle ":syntax case" command.
*/
static void
@@ -3244,9 +3339,9 @@ syn_cmd_case(eap, syncing)
next = skiptowhite(arg);
if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
- curbuf->b_syn_ic = FALSE;
+ curwin->w_s->b_syn_ic = FALSE;
else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6)
- curbuf->b_syn_ic = TRUE;
+ curwin->w_s->b_syn_ic = TRUE;
else
EMSG2(_("E390: Illegal argument: %s"), arg);
}
@@ -3268,11 +3363,11 @@ syn_cmd_spell(eap, syncing)
next = skiptowhite(arg);
if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
- curbuf->b_syn_spell = SYNSPL_TOP;
+ curwin->w_s->b_syn_spell = SYNSPL_TOP;
else if (STRNICMP(arg, "notoplevel", 10) == 0 && next - arg == 10)
- curbuf->b_syn_spell = SYNSPL_NOTOP;
+ curwin->w_s->b_syn_spell = SYNSPL_NOTOP;
else if (STRNICMP(arg, "default", 7) == 0 && next - arg == 7)
- curbuf->b_syn_spell = SYNSPL_DEFAULT;
+ curwin->w_s->b_syn_spell = SYNSPL_DEFAULT;
else
EMSG2(_("E390: Illegal argument: %s"), arg);
}
@@ -3281,47 +3376,47 @@ syn_cmd_spell(eap, syncing)
* Clear all syntax info for one buffer.
*/
void
-syntax_clear(buf)
- buf_T *buf;
+syntax_clear(block)
+ synblock_T *block;
{
int i;
- buf->b_syn_error = FALSE; /* clear previous error */
- buf->b_syn_ic = FALSE; /* Use case, by default */
- buf->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */
- buf->b_syn_containedin = FALSE;
+ block->b_syn_error = FALSE; /* clear previous error */
+ block->b_syn_ic = FALSE; /* Use case, by default */
+ block->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */
+ block->b_syn_containedin = FALSE;
/* free the keywords */
- clear_keywtab(&buf->b_keywtab);
- clear_keywtab(&buf->b_keywtab_ic);
+ clear_keywtab(&block->b_keywtab);
+ clear_keywtab(&block->b_keywtab_ic);
/* free the syntax patterns */
- for (i = buf->b_syn_patterns.ga_len; --i >= 0; )
- syn_clear_pattern(buf, i);
- ga_clear(&buf->b_syn_patterns);
+ for (i = block->b_syn_patterns.ga_len; --i >= 0; )
+ syn_clear_pattern(block, i);
+ ga_clear(&block->b_syn_patterns);
/* free the syntax clusters */
- for (i = buf->b_syn_clusters.ga_len; --i >= 0; )
- syn_clear_cluster(buf, i);
- ga_clear(&buf->b_syn_clusters);
- buf->b_spell_cluster_id = 0;
- buf->b_nospell_cluster_id = 0;
-
- buf->b_syn_sync_flags = 0;
- buf->b_syn_sync_minlines = 0;
- buf->b_syn_sync_maxlines = 0;
- buf->b_syn_sync_linebreaks = 0;
-
- vim_free(buf->b_syn_linecont_prog);
- buf->b_syn_linecont_prog = NULL;
- vim_free(buf->b_syn_linecont_pat);
- buf->b_syn_linecont_pat = NULL;
+ for (i = block->b_syn_clusters.ga_len; --i >= 0; )
+ syn_clear_cluster(block, i);
+ ga_clear(&block->b_syn_clusters);
+ block->b_spell_cluster_id = 0;
+ block->b_nospell_cluster_id = 0;
+
+ block->b_syn_sync_flags = 0;
+ block->b_syn_sync_minlines = 0;
+ block->b_syn_sync_maxlines = 0;
+ block->b_syn_sync_linebreaks = 0;
+
+ vim_free(block->b_syn_linecont_prog);
+ block->b_syn_linecont_prog = NULL;
+ vim_free(block->b_syn_linecont_pat);
+ block->b_syn_linecont_pat = NULL;
#ifdef FEAT_FOLDING
- buf->b_syn_folditems = 0;
+ block->b_syn_folditems = 0;
#endif
/* free the stored states */
- syn_stack_free_all(buf);
+ syn_stack_free_all(block);
invalidate_current_state();
}
@@ -3334,42 +3429,42 @@ syntax_sync_clear()
int i;
/* free the syntax patterns */
- for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; )
- if (SYN_ITEMS(curbuf)[i].sp_syncing)
- syn_remove_pattern(curbuf, i);
+ for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; )
+ if (SYN_ITEMS(curwin->w_s)[i].sp_syncing)
+ syn_remove_pattern(curwin->w_s, i);
- curbuf->b_syn_sync_flags = 0;
- curbuf->b_syn_sync_minlines = 0;
- curbuf->b_syn_sync_maxlines = 0;
- curbuf->b_syn_sync_linebreaks = 0;
+ curwin->w_s->b_syn_sync_flags = 0;
+ curwin->w_s->b_syn_sync_minlines = 0;
+ curwin->w_s->b_syn_sync_maxlines = 0;
+ curwin->w_s->b_syn_sync_linebreaks = 0;
- vim_free(curbuf->b_syn_linecont_prog);
- curbuf->b_syn_linecont_prog = NULL;
- vim_free(curbuf->b_syn_linecont_pat);
- curbuf->b_syn_linecont_pat = NULL;
+ vim_free(curwin->w_s->b_syn_linecont_prog);
+ curwin->w_s->b_syn_linecont_prog = NULL;
+ vim_free(curwin->w_s->b_syn_linecont_pat);
+ curwin->w_s->b_syn_linecont_pat = NULL;
- syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
}
/*
* Remove one pattern from the buffer's pattern list.
*/
static void
-syn_remove_pattern(buf, idx)
- buf_T *buf;
+syn_remove_pattern(block, idx)
+ synblock_T *block;
int idx;
{
synpat_T *spp;
- spp = &(SYN_ITEMS(buf)[idx]);
+ spp = &(SYN_ITEMS(block)[idx]);
#ifdef FEAT_FOLDING
if (spp->sp_flags & HL_FOLD)
- --buf->b_syn_folditems;
+ --block->b_syn_folditems;
#endif
- syn_clear_pattern(buf, idx);
+ syn_clear_pattern(block, idx);
mch_memmove(spp, spp + 1,
- sizeof(synpat_T) * (buf->b_syn_patterns.ga_len - idx - 1));
- --buf->b_syn_patterns.ga_len;
+ sizeof(synpat_T) * (block->b_syn_patterns.ga_len - idx - 1));
+ --block->b_syn_patterns.ga_len;
}
/*
@@ -3377,18 +3472,18 @@ syn_remove_pattern(buf, idx)
* last to first!
*/
static void
-syn_clear_pattern(buf, i)
- buf_T *buf;
+syn_clear_pattern(block, i)
+ synblock_T *block;
int i;
{
- vim_free(SYN_ITEMS(buf)[i].sp_pattern);
- vim_free(SYN_ITEMS(buf)[i].sp_prog);
+ vim_free(SYN_ITEMS(block)[i].sp_pattern);
+ vim_free(SYN_ITEMS(block)[i].sp_prog);
/* Only free sp_cont_list and sp_next_list of first start pattern */
- if (i == 0 || SYN_ITEMS(buf)[i - 1].sp_type != SPTYPE_START)
+ if (i == 0 || SYN_ITEMS(block)[i - 1].sp_type != SPTYPE_START)
{
- vim_free(SYN_ITEMS(buf)[i].sp_cont_list);
- vim_free(SYN_ITEMS(buf)[i].sp_next_list);
- vim_free(SYN_ITEMS(buf)[i].sp_syn.cont_in_list);
+ vim_free(SYN_ITEMS(block)[i].sp_cont_list);
+ vim_free(SYN_ITEMS(block)[i].sp_next_list);
+ vim_free(SYN_ITEMS(block)[i].sp_syn.cont_in_list);
}
}
@@ -3396,13 +3491,13 @@ syn_clear_pattern(buf, i)
* Clear and free one syntax cluster.
*/
static void
-syn_clear_cluster(buf, i)
- buf_T *buf;
+syn_clear_cluster(block, i)
+ synblock_T *block;
int i;
{
- vim_free(SYN_CLSTR(buf)[i].scl_name);
- vim_free(SYN_CLSTR(buf)[i].scl_name_u);
- vim_free(SYN_CLSTR(buf)[i].scl_list);
+ vim_free(SYN_CLSTR(block)[i].scl_name);
+ vim_free(SYN_CLSTR(block)[i].scl_name_u);
+ vim_free(SYN_CLSTR(block)[i].scl_list);
}
/*
@@ -3427,7 +3522,7 @@ syn_cmd_clear(eap, syncing)
* Only required for Vim 5.x syntax files, 6.0 ones don't contain ":syn
* clear".
*/
- if (curbuf->b_syn_topgrp != 0)
+ if (curwin->w_s->b_syn_topgrp != 0)
return;
if (ends_excmd(*arg))
@@ -3439,8 +3534,12 @@ syn_cmd_clear(eap, syncing)
syntax_sync_clear();
else
{
- syntax_clear(curbuf);
- do_unlet((char_u *)"b:current_syntax", TRUE);
+ syntax_clear(curwin->w_s);
+ if (curwin->w_s == &curwin->w_buffer->b_s)
+ do_unlet((char_u *)"b:current_syntax", TRUE);
+ else
+ do_unlet((char_u *)"w:current_syntax", TRUE);
+
}
}
else
@@ -3468,8 +3567,8 @@ syn_cmd_clear(eap, syncing)
*/
short scl_id = id - SYNID_CLUSTER;
- vim_free(SYN_CLSTR(curbuf)[scl_id].scl_list);
- SYN_CLSTR(curbuf)[scl_id].scl_list = NULL;
+ vim_free(SYN_CLSTR(curwin->w_s)[scl_id].scl_list);
+ SYN_CLSTR(curwin->w_s)[scl_id].scl_list = NULL;
}
}
else
@@ -3487,7 +3586,7 @@ syn_cmd_clear(eap, syncing)
}
}
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
}
/*
@@ -3504,17 +3603,17 @@ syn_clear_one(id, syncing)
/* Clear keywords only when not ":syn sync clear group-name" */
if (!syncing)
{
- (void)syn_clear_keyword(id, &curbuf->b_keywtab);
- (void)syn_clear_keyword(id, &curbuf->b_keywtab_ic);
+ (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab);
+ (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab_ic);
}
/* clear the patterns for "id" */
- for (idx = curbuf->b_syn_patterns.ga_len; --idx >= 0; )
+ for (idx = curwin->w_s->b_syn_patterns.ga_len; --idx >= 0; )
{
- spp = &(SYN_ITEMS(curbuf)[idx]);
+ spp = &(SYN_ITEMS(curwin->w_s)[idx]);
if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
continue;
- syn_remove_pattern(curbuf, idx);
+ syn_remove_pattern(curwin->w_s, idx);
}
}
@@ -3613,7 +3712,7 @@ syn_cmd_list(eap, syncing)
if (eap->skip)
return;
- if (!syntax_present(curbuf))
+ if (!syntax_present(curwin))
{
MSG(_("No Syntax items defined for this buffer"));
return;
@@ -3621,30 +3720,30 @@ syn_cmd_list(eap, syncing)
if (syncing)
{
- if (curbuf->b_syn_sync_flags & SF_CCOMMENT)
+ if (curwin->w_s->b_syn_sync_flags & SF_CCOMMENT)
{
MSG_PUTS(_("syncing on C-style comments"));
syn_lines_msg();
syn_match_msg();
return;
}
- else if (!(curbuf->b_syn_sync_flags & SF_MATCH))
+ else if (!(curwin->w_s->b_syn_sync_flags & SF_MATCH))
{
- if (curbuf->b_syn_sync_minlines == 0)
+ if (curwin->w_s->b_syn_sync_minlines == 0)
MSG_PUTS(_("no syncing"));
else
{
MSG_PUTS(_("syncing starts "));
- msg_outnum(curbuf->b_syn_sync_minlines);
+ msg_outnum(curwin->w_s->b_syn_sync_minlines);
MSG_PUTS(_(" lines before top line"));
syn_match_msg();
}
return;
}
MSG_PUTS_TITLE(_("\n--- Syntax sync items ---"));
- if (curbuf->b_syn_sync_minlines > 0
- || curbuf->b_syn_sync_maxlines > 0
- || curbuf->b_syn_sync_linebreaks > 0)
+ if (curwin->w_s->b_syn_sync_minlines > 0
+ || curwin->w_s->b_syn_sync_maxlines > 0
+ || curwin->w_s->b_syn_sync_linebreaks > 0)
{
MSG_PUTS(_("\nsyncing on items"));
syn_lines_msg();
@@ -3660,7 +3759,7 @@ syn_cmd_list(eap, syncing)
*/
for (id = 1; id <= highlight_ga.ga_len && !got_int; ++id)
syn_list_one(id, syncing, FALSE);
- for (id = 0; id < curbuf->b_syn_clusters.ga_len && !got_int; ++id)
+ for (id = 0; id < curwin->w_s->b_syn_clusters.ga_len && !got_int; ++id)
syn_list_cluster(id);
}
else
@@ -3696,20 +3795,21 @@ syn_cmd_list(eap, syncing)
static void
syn_lines_msg()
{
- if (curbuf->b_syn_sync_maxlines > 0 || curbuf->b_syn_sync_minlines > 0)
+ if (curwin->w_s->b_syn_sync_maxlines > 0
+ || curwin->w_s->b_syn_sync_minlines > 0)
{
MSG_PUTS("; ");
- if (curbuf->b_syn_sync_minlines > 0)
+ if (curwin->w_s->b_syn_sync_minlines > 0)
{
MSG_PUTS(_("minimal "));
- msg_outnum(curbuf->b_syn_sync_minlines);
- if (curbuf->b_syn_sync_maxlines)
+ msg_outnum(curwin->w_s->b_syn_sync_minlines);
+ if (curwin->w_s->b_syn_sync_maxlines)
MSG_PUTS(", ");
}
- if (curbuf->b_syn_sync_maxlines > 0)
+ if (curwin->w_s->b_syn_sync_maxlines > 0)
{
MSG_PUTS(_("maximal "));
- msg_outnum(curbuf->b_syn_sync_maxlines);
+ msg_outnum(curwin->w_s->b_syn_sync_maxlines);
}
MSG_PUTS(_(" lines before top line"));
}
@@ -3718,10 +3818,10 @@ syn_lines_msg()
static void
syn_match_msg()
{
- if (curbuf->b_syn_sync_linebreaks > 0)
+ if (curwin->w_s->b_syn_sync_linebreaks > 0)
{
MSG_PUTS(_("; match "));
- msg_outnum(curbuf->b_syn_sync_linebreaks);
+ msg_outnum(curwin->w_s->b_syn_sync_linebreaks);
MSG_PUTS(_(" line breaks"));
}
}
@@ -3759,6 +3859,10 @@ syn_list_one(id, syncing, link_only)
{HL_EXCLUDENL, "excludenl"},
{HL_TRANSP, "transparent"},
{HL_FOLD, "fold"},
+#ifdef FEAT_CONCEAL
+ {HL_CONCEAL, "conceal"},
+ {HL_CONCEALENDS, "concealends"},
+#endif
{0, NULL}
};
static struct name_list namelist2[] =
@@ -3774,15 +3878,15 @@ syn_list_one(id, syncing, link_only)
/* list the keywords for "id" */
if (!syncing)
{
- did_header = syn_list_keywords(id, &curbuf->b_keywtab, FALSE, attr);
- did_header = syn_list_keywords(id, &curbuf->b_keywtab_ic,
+ did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, FALSE, attr);
+ did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab_ic,
did_header, attr);
}
/* list the patterns for "id" */
- for (idx = 0; idx < curbuf->b_syn_patterns.ga_len && !got_int; ++idx)
+ for (idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len && !got_int; ++idx)
{
- spp = &(SYN_ITEMS(curbuf)[idx]);
+ spp = &(SYN_ITEMS(curwin->w_s)[idx]);
if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
continue;
@@ -3796,13 +3900,13 @@ syn_list_one(id, syncing, link_only)
}
else if (spp->sp_type == SPTYPE_START)
{
- while (SYN_ITEMS(curbuf)[idx].sp_type == SPTYPE_START)
- put_pattern("start", '=', &SYN_ITEMS(curbuf)[idx++], attr);
- if (SYN_ITEMS(curbuf)[idx].sp_type == SPTYPE_SKIP)
- put_pattern("skip", '=', &SYN_ITEMS(curbuf)[idx++], attr);
- while (idx < curbuf->b_syn_patterns.ga_len
- && SYN_ITEMS(curbuf)[idx].sp_type == SPTYPE_END)
- put_pattern("end", '=', &SYN_ITEMS(curbuf)[idx++], attr);
+ while (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_START)
+ put_pattern("start", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
+ if (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_SKIP)
+ put_pattern("skip", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
+ while (idx < curwin->w_s->b_syn_patterns.ga_len
+ && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END)
+ put_pattern("end", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
--idx;
msg_putchar(' ');
}
@@ -3828,7 +3932,7 @@ syn_list_one(id, syncing, link_only)
msg_puts_attr((char_u *)"groupthere", attr);
msg_putchar(' ');
if (spp->sp_sync_idx >= 0)
- msg_outtrans(HL_TABLE()[SYN_ITEMS(curbuf)
+ msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s)
[spp->sp_sync_idx].sp_syn.id - 1].sg_name);
else
MSG_PUTS("NONE");
@@ -3873,7 +3977,7 @@ syn_list_cluster(id)
/* slight hack: roughly duplicate the guts of syn_list_header() */
msg_putchar('\n');
- msg_outtrans(SYN_CLSTR(curbuf)[id].scl_name);
+ msg_outtrans(SYN_CLSTR(curwin->w_s)[id].scl_name);
if (msg_col >= endcol) /* output at least one space */
endcol = msg_col + 1;
@@ -3881,9 +3985,9 @@ syn_list_cluster(id)
endcol = Columns - 1;
msg_advance(endcol);
- if (SYN_CLSTR(curbuf)[id].scl_list != NULL)
+ if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL)
{
- put_id_list((char_u *)"cluster", SYN_CLSTR(curbuf)[id].scl_list,
+ put_id_list((char_u *)"cluster", SYN_CLSTR(curwin->w_s)[id].scl_list,
hl_attr(HLF_D));
}
else
@@ -3925,7 +4029,7 @@ put_id_list(name, list, attr)
short scl_id = *p - SYNID_CLUSTER;
msg_putchar('@');
- msg_outtrans(SYN_CLSTR(curbuf)[scl_id].scl_name);
+ msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name);
}
else
msg_outtrans(HL_TABLE()[*p - 1].sg_name);
@@ -4190,12 +4294,13 @@ clear_keywtab(ht)
* Add a keyword to the list of keywords.
*/
static void
-add_keyword(name, id, flags, cont_in_list, next_list)
+add_keyword(name, id, flags, cont_in_list, next_list, conceal_char)
char_u *name; /* name of keyword */
int id; /* group ID for this keyword */
int flags; /* flags for this keyword */
short *cont_in_list; /* containedin for this keyword */
short *next_list; /* nextgroup for this keyword */
+ int conceal_char;
{
keyentry_T *kp;
hashtab_T *ht;
@@ -4204,7 +4309,7 @@ add_keyword(name, id, flags, cont_in_list, next_list)
long_u hash;
char_u name_folded[MAXKEYWLEN + 1];
- if (curbuf->b_syn_ic)
+ if (curwin->w_s->b_syn_ic)
name_ic = str_foldcase(name, (int)STRLEN(name),
name_folded, MAXKEYWLEN + 1);
else
@@ -4216,15 +4321,16 @@ add_keyword(name, id, flags, cont_in_list, next_list)
kp->k_syn.id = id;
kp->k_syn.inc_tag = current_syn_inc_tag;
kp->flags = flags;
+ kp->k_char = conceal_char;
kp->k_syn.cont_in_list = copy_id_list(cont_in_list);
if (cont_in_list != NULL)
- curbuf->b_syn_containedin = TRUE;
+ curwin->w_s->b_syn_containedin = TRUE;
kp->next_list = copy_id_list(next_list);
- if (curbuf->b_syn_ic)
- ht = &curbuf->b_keywtab_ic;
+ if (curwin->w_s->b_syn_ic)
+ ht = &curwin->w_s->b_keywtab_ic;
else
- ht = &curbuf->b_keywtab;
+ ht = &curwin->w_s->b_keywtab;
hash = hash_hash(kp->keyword);
hi = hash_lookup(ht, kp->keyword, hash);
@@ -4275,9 +4381,10 @@ get_group_name(arg, name_end)
* Return NULL for any error;
*/
static char_u *
-get_syn_options(arg, opt)
+get_syn_options(arg, opt, conceal_char)
char_u *arg; /* next argument to be checked */
syn_opt_arg_T *opt; /* various things */
+ int *conceal_char UNUSED;
{
char_u *gname_start, *gname;
int syn_id;
@@ -4303,6 +4410,9 @@ get_syn_options(arg, opt)
{"gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE},
{"dDiIsSpPlLaAyY", 0, HL_DISPLAY},
{"fFoOlLdD", 0, HL_FOLD},
+ {"cCoOnNcCeEaAlL", 0, HL_CONCEAL},
+ {"cCoOnNcCeEaAlLeEnNdDsS", 0, HL_CONCEALENDS},
+ {"cCcChHaArR", 11, 0},
{"cCoOnNtTaAiInNsS", 1, 0},
{"cCoOnNtTaAiInNeEdDiInN", 2, 0},
{"nNeExXtTgGrRoOuUpP", 3, 0},
@@ -4312,6 +4422,11 @@ get_syn_options(arg, opt)
if (arg == NULL) /* already detected error */
return NULL;
+#ifdef FEAT_CONCEAL
+ if (curwin->w_s->b_syn_conceal)
+ opt->flags |= HL_CONCEAL;
+#endif
+
for (;;)
{
/*
@@ -4372,6 +4487,26 @@ get_syn_options(arg, opt)
if (get_id_list(&arg, 9, &opt->next_list) == FAIL)
return NULL;
}
+ else if (flagtab[fidx].argtype == 11 && arg[5] == '=')
+ {
+#ifdef FEAT_MBYTE
+ /* cchar=? */
+ if (has_mbyte)
+ {
+# ifdef FEAT_CONCEAL
+ *conceal_char = mb_ptr2char(arg + 6);
+# endif
+ arg += mb_ptr2len(arg + 6) - 1;
+ }
+ else
+#endif
+#ifdef FEAT_CONCEAL
+ *conceal_char = arg[6];
+#else
+ ;
+#endif
+ arg = skipwhite(arg + 7);
+ }
else
{
opt->flags |= flagtab[fidx].flags;
@@ -4397,9 +4532,9 @@ get_syn_options(arg, opt)
else
{
syn_id = syn_name2id(gname);
- for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; )
- if (SYN_ITEMS(curbuf)[i].sp_syn.id == syn_id
- && SYN_ITEMS(curbuf)[i].sp_type == SPTYPE_START)
+ for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; )
+ if (SYN_ITEMS(curwin->w_s)[i].sp_syn.id == syn_id
+ && SYN_ITEMS(curwin->w_s)[i].sp_type == SPTYPE_START)
{
*opt->sync_idx = i;
break;
@@ -4437,20 +4572,20 @@ syn_incl_toplevel(id, flagsp)
int id;
int *flagsp;
{
- if ((*flagsp & HL_CONTAINED) || curbuf->b_syn_topgrp == 0)
+ if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0)
return;
*flagsp |= HL_CONTAINED;
- if (curbuf->b_syn_topgrp >= SYNID_CLUSTER)
+ if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER)
{
/* We have to alloc this, because syn_combine_list() will free it. */
short *grp_list = (short *)alloc((unsigned)(2 * sizeof(short)));
- int tlg_id = curbuf->b_syn_topgrp - SYNID_CLUSTER;
+ int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER;
if (grp_list != NULL)
{
grp_list[0] = id;
grp_list[1] = 0;
- syn_combine_list(&SYN_CLSTR(curbuf)[tlg_id].scl_list, &grp_list,
+ syn_combine_list(&SYN_CLSTR(curwin->w_s)[tlg_id].scl_list, &grp_list,
CLUSTER_ADD);
}
}
@@ -4517,12 +4652,12 @@ syn_cmd_include(eap, syncing)
*/
prev_syn_inc_tag = current_syn_inc_tag;
current_syn_inc_tag = ++running_syn_inc_tag;
- prev_toplvl_grp = curbuf->b_syn_topgrp;
- curbuf->b_syn_topgrp = sgl_id;
+ prev_toplvl_grp = curwin->w_s->b_syn_topgrp;
+ curwin->w_s->b_syn_topgrp = sgl_id;
if (source ? do_source(eap->arg, FALSE, DOSO_NONE) == FAIL
: source_runtime(eap->arg, TRUE) == FAIL)
EMSG2(_(e_notopen), eap->arg);
- curbuf->b_syn_topgrp = prev_toplvl_grp;
+ curwin->w_s->b_syn_topgrp = prev_toplvl_grp;
current_syn_inc_tag = prev_syn_inc_tag;
}
@@ -4543,6 +4678,7 @@ syn_cmd_keyword(eap, syncing)
char_u *kw;
syn_opt_arg_T syn_opt_arg;
int cnt;
+ int conceal_char = NUL;
rest = get_group_name(arg, &group_name_end);
@@ -4570,7 +4706,7 @@ syn_cmd_keyword(eap, syncing)
p = keyword_copy;
for ( ; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest))
{
- rest = get_syn_options(rest, &syn_opt_arg);
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
if (rest == NULL || ends_excmd(*rest))
break;
/* Copy the keyword, removing backslashes, and add a NUL. */
@@ -4599,8 +4735,8 @@ syn_cmd_keyword(eap, syncing)
if (p != NULL)
*p = NUL;
add_keyword(kw, syn_id, syn_opt_arg.flags,
- syn_opt_arg.cont_in_list,
- syn_opt_arg.next_list);
+ syn_opt_arg.cont_in_list,
+ syn_opt_arg.next_list, conceal_char);
if (p == NULL)
break;
if (p[1] == NUL)
@@ -4644,7 +4780,7 @@ syn_cmd_keyword(eap, syncing)
EMSG2(_(e_invarg2), arg);
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
}
/*
@@ -4665,6 +4801,7 @@ syn_cmd_match(eap, syncing)
int idx;
syn_opt_arg_T syn_opt_arg;
int sync_idx = 0;
+ int conceal_char = NUL;
/* Isolate the group name, check for validity */
rest = get_group_name(arg, &group_name_end);
@@ -4677,7 +4814,7 @@ syn_cmd_match(eap, syncing)
syn_opt_arg.cont_list = NULL;
syn_opt_arg.cont_in_list = NULL;
syn_opt_arg.next_list = NULL;
- rest = get_syn_options(rest, &syn_opt_arg);
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
/* get the pattern. */
init_syn_patterns();
@@ -4687,7 +4824,7 @@ syn_cmd_match(eap, syncing)
syn_opt_arg.flags |= HL_HAS_EOL;
/* Get options after the pattern */
- rest = get_syn_options(rest, &syn_opt_arg);
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
if (rest != NULL) /* all arguments are valid */
{
@@ -4697,7 +4834,7 @@ syn_cmd_match(eap, syncing)
eap->nextcmd = check_nextcmd(rest);
if (!ends_excmd(*rest) || eap->skip)
rest = NULL;
- else if (ga_grow(&curbuf->b_syn_patterns, 1) != FAIL
+ else if (ga_grow(&curwin->w_s->b_syn_patterns, 1) != FAIL
&& (syn_id = syn_check_group(arg,
(int)(group_name_end - arg))) != 0)
{
@@ -4705,32 +4842,35 @@ syn_cmd_match(eap, syncing)
/*
* Store the pattern in the syn_items list
*/
- idx = curbuf->b_syn_patterns.ga_len;
- SYN_ITEMS(curbuf)[idx] = item;
- SYN_ITEMS(curbuf)[idx].sp_syncing = syncing;
- SYN_ITEMS(curbuf)[idx].sp_type = SPTYPE_MATCH;
- SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id;
- SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag;
- SYN_ITEMS(curbuf)[idx].sp_flags = syn_opt_arg.flags;
- SYN_ITEMS(curbuf)[idx].sp_sync_idx = sync_idx;
- SYN_ITEMS(curbuf)[idx].sp_cont_list = syn_opt_arg.cont_list;
- SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list =
+ idx = curwin->w_s->b_syn_patterns.ga_len;
+ SYN_ITEMS(curwin->w_s)[idx] = item;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syncing = syncing;
+ SYN_ITEMS(curwin->w_s)[idx].sp_type = SPTYPE_MATCH;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.id = syn_id;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.inc_tag = current_syn_inc_tag;
+ SYN_ITEMS(curwin->w_s)[idx].sp_flags = syn_opt_arg.flags;
+ SYN_ITEMS(curwin->w_s)[idx].sp_sync_idx = sync_idx;
+ SYN_ITEMS(curwin->w_s)[idx].sp_cont_list = syn_opt_arg.cont_list;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.cont_in_list =
syn_opt_arg.cont_in_list;
+#ifdef FEAT_CONCEAL
+ SYN_ITEMS(curwin->w_s)[idx].sp_char = conceal_char;
+#endif
if (syn_opt_arg.cont_in_list != NULL)
- curbuf->b_syn_containedin = TRUE;
- SYN_ITEMS(curbuf)[idx].sp_next_list = syn_opt_arg.next_list;
- ++curbuf->b_syn_patterns.ga_len;
+ curwin->w_s->b_syn_containedin = TRUE;
+ SYN_ITEMS(curwin->w_s)[idx].sp_next_list = syn_opt_arg.next_list;
+ ++curwin->w_s->b_syn_patterns.ga_len;
/* remember that we found a match for syncing on */
if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE))
- curbuf->b_syn_sync_flags |= SF_MATCH;
+ curwin->w_s->b_syn_sync_flags |= SF_MATCH;
#ifdef FEAT_FOLDING
if (syn_opt_arg.flags & HL_FOLD)
- ++curbuf->b_syn_folditems;
+ ++curwin->w_s->b_syn_folditems;
#endif
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
return; /* don't free the progs and patterns now */
}
}
@@ -4785,6 +4925,7 @@ syn_cmd_region(eap, syncing)
int success = FALSE;
int idx;
syn_opt_arg_T syn_opt_arg;
+ int conceal_char = NUL;
/* Isolate the group name, check for validity */
rest = get_group_name(arg, &group_name_end);
@@ -4809,7 +4950,7 @@ syn_cmd_region(eap, syncing)
while (rest != NULL && !ends_excmd(*rest))
{
/* Check for option arguments */
- rest = get_syn_options(rest, &syn_opt_arg);
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
if (rest == NULL || ends_excmd(*rest))
break;
@@ -4933,7 +5074,7 @@ syn_cmd_region(eap, syncing)
eap->nextcmd = check_nextcmd(rest);
if (!ends_excmd(*rest) || eap->skip)
rest = NULL;
- else if (ga_grow(&(curbuf->b_syn_patterns), pat_count) != FAIL
+ else if (ga_grow(&(curwin->w_s->b_syn_patterns), pat_count) != FAIL
&& (syn_id = syn_check_group(arg,
(int)(group_name_end - arg))) != 0)
{
@@ -4941,43 +5082,46 @@ syn_cmd_region(eap, syncing)
/*
* Store the start/skip/end in the syn_items list
*/
- idx = curbuf->b_syn_patterns.ga_len;
+ idx = curwin->w_s->b_syn_patterns.ga_len;
for (item = ITEM_START; item <= ITEM_END; ++item)
{
for (ppp = pat_ptrs[item]; ppp != NULL; ppp = ppp->pp_next)
{
- SYN_ITEMS(curbuf)[idx] = *(ppp->pp_synp);
- SYN_ITEMS(curbuf)[idx].sp_syncing = syncing;
- SYN_ITEMS(curbuf)[idx].sp_type =
+ SYN_ITEMS(curwin->w_s)[idx] = *(ppp->pp_synp);
+ SYN_ITEMS(curwin->w_s)[idx].sp_syncing = syncing;
+ SYN_ITEMS(curwin->w_s)[idx].sp_type =
(item == ITEM_START) ? SPTYPE_START :
(item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END;
- SYN_ITEMS(curbuf)[idx].sp_flags |= syn_opt_arg.flags;
- SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id;
- SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag;
- SYN_ITEMS(curbuf)[idx].sp_syn_match_id =
+ SYN_ITEMS(curwin->w_s)[idx].sp_flags |= syn_opt_arg.flags;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.id = syn_id;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.inc_tag = current_syn_inc_tag;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn_match_id =
ppp->pp_matchgroup_id;
+#ifdef FEAT_CONCEAL
+ SYN_ITEMS(curwin->w_s)[idx].sp_char = conceal_char;
+#endif
if (item == ITEM_START)
{
- SYN_ITEMS(curbuf)[idx].sp_cont_list =
+ SYN_ITEMS(curwin->w_s)[idx].sp_cont_list =
syn_opt_arg.cont_list;
- SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list =
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.cont_in_list =
syn_opt_arg.cont_in_list;
if (syn_opt_arg.cont_in_list != NULL)
- curbuf->b_syn_containedin = TRUE;
- SYN_ITEMS(curbuf)[idx].sp_next_list =
+ curwin->w_s->b_syn_containedin = TRUE;
+ SYN_ITEMS(curwin->w_s)[idx].sp_next_list =
syn_opt_arg.next_list;
}
- ++curbuf->b_syn_patterns.ga_len;
+ ++curwin->w_s->b_syn_patterns.ga_len;
++idx;
#ifdef FEAT_FOLDING
if (syn_opt_arg.flags & HL_FOLD)
- ++curbuf->b_syn_folditems;
+ ++curwin->w_s->b_syn_folditems;
#endif
}
}
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
success = TRUE; /* don't free the progs and patterns now */
}
}
@@ -5169,9 +5313,9 @@ syn_scl_name2id(name)
name_u = vim_strsave_up(name);
if (name_u == NULL)
return 0;
- for (i = curbuf->b_syn_clusters.ga_len; --i >= 0; )
- if (SYN_CLSTR(curbuf)[i].scl_name_u != NULL
- && STRCMP(name_u, SYN_CLSTR(curbuf)[i].scl_name_u) == 0)
+ for (i = curwin->w_s->b_syn_clusters.ga_len; --i >= 0; )
+ if (SYN_CLSTR(curwin->w_s)[i].scl_name_u != NULL
+ && STRCMP(name_u, SYN_CLSTR(curwin->w_s)[i].scl_name_u) == 0)
break;
vim_free(name_u);
return (i < 0 ? 0 : i + SYNID_CLUSTER);
@@ -5237,32 +5381,32 @@ syn_add_cluster(name)
/*
* First call for this growarray: init growing array.
*/
- if (curbuf->b_syn_clusters.ga_data == NULL)
+ if (curwin->w_s->b_syn_clusters.ga_data == NULL)
{
- curbuf->b_syn_clusters.ga_itemsize = sizeof(syn_cluster_T);
- curbuf->b_syn_clusters.ga_growsize = 10;
+ curwin->w_s->b_syn_clusters.ga_itemsize = sizeof(syn_cluster_T);
+ curwin->w_s->b_syn_clusters.ga_growsize = 10;
}
/*
* Make room for at least one other cluster entry.
*/
- if (ga_grow(&curbuf->b_syn_clusters, 1) == FAIL)
+ if (ga_grow(&curwin->w_s->b_syn_clusters, 1) == FAIL)
{
vim_free(name);
return 0;
}
- len = curbuf->b_syn_clusters.ga_len;
+ len = curwin->w_s->b_syn_clusters.ga_len;
- vim_memset(&(SYN_CLSTR(curbuf)[len]), 0, sizeof(syn_cluster_T));
- SYN_CLSTR(curbuf)[len].scl_name = name;
- SYN_CLSTR(curbuf)[len].scl_name_u = vim_strsave_up(name);
- SYN_CLSTR(curbuf)[len].scl_list = NULL;
- ++curbuf->b_syn_clusters.ga_len;
+ vim_memset(&(SYN_CLSTR(curwin->w_s)[len]), 0, sizeof(syn_cluster_T));
+ SYN_CLSTR(curwin->w_s)[len].scl_name = name;
+ SYN_CLSTR(curwin->w_s)[len].scl_name_u = vim_strsave_up(name);
+ SYN_CLSTR(curwin->w_s)[len].scl_list = NULL;
+ ++curwin->w_s->b_syn_clusters.ga_len;
if (STRICMP(name, "Spell") == 0)
- curbuf->b_spell_cluster_id = len + SYNID_CLUSTER;
+ curwin->w_s->b_spell_cluster_id = len + SYNID_CLUSTER;
if (STRICMP(name, "NoSpell") == 0)
- curbuf->b_nospell_cluster_id = len + SYNID_CLUSTER;
+ curwin->w_s->b_nospell_cluster_id = len + SYNID_CLUSTER;
return len + SYNID_CLUSTER;
}
@@ -5325,7 +5469,7 @@ syn_cmd_cluster(eap, syncing)
EMSG2(_(e_invarg2), rest);
break;
}
- syn_combine_list(&SYN_CLSTR(curbuf)[scl_id].scl_list,
+ syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
&clstr_list, list_op);
got_clstr = TRUE;
}
@@ -5333,7 +5477,7 @@ syn_cmd_cluster(eap, syncing)
if (got_clstr)
{
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
}
}
@@ -5349,8 +5493,8 @@ syn_cmd_cluster(eap, syncing)
static void
init_syn_patterns()
{
- curbuf->b_syn_patterns.ga_itemsize = sizeof(synpat_T);
- curbuf->b_syn_patterns.ga_growsize = 10;
+ curwin->w_s->b_syn_patterns.ga_itemsize = sizeof(synpat_T);
+ curwin->w_s->b_syn_patterns.ga_growsize = 10;
}
/*
@@ -5390,7 +5534,7 @@ get_syn_pattern(arg, ci)
if (ci->sp_prog == NULL)
return NULL;
- ci->sp_ic = curbuf->b_syn_ic;
+ ci->sp_ic = curwin->w_s->b_syn_ic;
/*
* Check for a match, highlight or region offset.
@@ -5488,17 +5632,17 @@ syn_cmd_sync(eap, syncing)
if (STRCMP(key, "CCOMMENT") == 0)
{
if (!eap->skip)
- curbuf->b_syn_sync_flags |= SF_CCOMMENT;
+ curwin->w_s->b_syn_sync_flags |= SF_CCOMMENT;
if (!ends_excmd(*next_arg))
{
arg_end = skiptowhite(next_arg);
if (!eap->skip)
- curbuf->b_syn_sync_id = syn_check_group(next_arg,
+ curwin->w_s->b_syn_sync_id = syn_check_group(next_arg,
(int)(arg_end - next_arg));
next_arg = skipwhite(arg_end);
}
else if (!eap->skip)
- curbuf->b_syn_sync_id = syn_name2id((char_u *)"Comment");
+ curwin->w_s->b_syn_sync_id = syn_name2id((char_u *)"Comment");
}
else if ( STRNCMP(key, "LINES", 5) == 0
|| STRNCMP(key, "MINLINES", 8) == 0
@@ -5520,24 +5664,24 @@ syn_cmd_sync(eap, syncing)
if (!eap->skip)
{
if (key[4] == 'B')
- curbuf->b_syn_sync_linebreaks = n;
+ curwin->w_s->b_syn_sync_linebreaks = n;
else if (key[1] == 'A')
- curbuf->b_syn_sync_maxlines = n;
+ curwin->w_s->b_syn_sync_maxlines = n;
else
- curbuf->b_syn_sync_minlines = n;
+ curwin->w_s->b_syn_sync_minlines = n;
}
}
else if (STRCMP(key, "FROMSTART") == 0)
{
if (!eap->skip)
{
- curbuf->b_syn_sync_minlines = MAXLNUM;
- curbuf->b_syn_sync_maxlines = 0;
+ curwin->w_s->b_syn_sync_minlines = MAXLNUM;
+ curwin->w_s->b_syn_sync_maxlines = 0;
}
}
else if (STRCMP(key, "LINECONT") == 0)
{
- if (curbuf->b_syn_linecont_pat != NULL)
+ if (curwin->w_s->b_syn_linecont_pat != NULL)
{
EMSG(_("E403: syntax sync: line continuations pattern specified twice"));
finished = TRUE;
@@ -5553,25 +5697,25 @@ syn_cmd_sync(eap, syncing)
if (!eap->skip)
{
/* store the pattern and compiled regexp program */
- if ((curbuf->b_syn_linecont_pat = vim_strnsave(next_arg + 1,
+ if ((curwin->w_s->b_syn_linecont_pat = vim_strnsave(next_arg + 1,
(int)(arg_end - next_arg - 1))) == NULL)
{
finished = TRUE;
break;
}
- curbuf->b_syn_linecont_ic = curbuf->b_syn_ic;
+ curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic;
/* Make 'cpoptions' empty, to avoid the 'l' flag */
cpo_save = p_cpo;
p_cpo = (char_u *)"";
- curbuf->b_syn_linecont_prog =
- vim_regcomp(curbuf->b_syn_linecont_pat, RE_MAGIC);
+ curwin->w_s->b_syn_linecont_prog =
+ vim_regcomp(curwin->w_s->b_syn_linecont_pat, RE_MAGIC);
p_cpo = cpo_save;
- if (curbuf->b_syn_linecont_prog == NULL)
+ if (curwin->w_s->b_syn_linecont_prog == NULL)
{
- vim_free(curbuf->b_syn_linecont_pat);
- curbuf->b_syn_linecont_pat = NULL;
+ vim_free(curwin->w_s->b_syn_linecont_pat);
+ curwin->w_s->b_syn_linecont_pat = NULL;
finished = TRUE;
break;
}
@@ -5601,7 +5745,7 @@ syn_cmd_sync(eap, syncing)
{
eap->nextcmd = check_nextcmd(arg_start);
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
}
}
@@ -5862,8 +6006,8 @@ in_id_list(cur_si, list, ssp, contained)
--cur_si;
/* cur_si->si_idx is -1 for keywords, these never contain anything. */
if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list,
- &(SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_syn),
- SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_flags & HL_CONTAINED))
+ &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn),
+ SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & HL_CONTAINED))
return TRUE;
}
@@ -5918,7 +6062,7 @@ in_id_list(cur_si, list, ssp, contained)
return retval;
if (item >= SYNID_CLUSTER)
{
- scl_list = SYN_CLSTR(syn_buf)[item - SYNID_CLUSTER].scl_list;
+ scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list;
/* restrict recursiveness to 30 to avoid an endless loop for a
* cluster that includes itself (indirectly) */
if (scl_list != NULL && depth < 30)
@@ -5946,6 +6090,7 @@ static struct subcommand subcommands[] =
{"case", syn_cmd_case},
{"clear", syn_cmd_clear},
{"cluster", syn_cmd_cluster},
+ {"conceal", syn_cmd_conceal},
{"enable", syn_cmd_enable},
{"include", syn_cmd_include},
{"keyword", syn_cmd_keyword},
@@ -6006,14 +6151,34 @@ ex_syntax(eap)
}
}
+ void
+ex_ownsyntax(eap)
+ exarg_T *eap;
+{
+ if (curwin->w_s == &curwin->w_buffer->b_s)
+ {
+ curwin->w_s = (synblock_T *)alloc(sizeof(synblock_T));
+ memset(curwin->w_s, 0, sizeof(synblock_T));
+#ifdef FEAT_SPELL
+ curwin->w_p_spell = FALSE; /* No spell checking */
+ clear_string_option(&curwin->w_s->b_p_spc);
+ clear_string_option(&curwin->w_s->b_p_spf);
+ vim_free(curwin->w_s->b_cap_prog);
+ curwin->w_s->b_cap_prog = NULL;
+ clear_string_option(&curwin->w_s->b_p_spl);
+#endif
+ }
+ apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf);
+}
+
int
-syntax_present(buf)
- buf_T *buf;
+syntax_present(win)
+ win_T *win;
{
- return (buf->b_syn_patterns.ga_len != 0
- || buf->b_syn_clusters.ga_len != 0
- || buf->b_keywtab.ht_used > 0
- || buf->b_keywtab_ic.ht_used > 0);
+ return (win->w_s->b_syn_patterns.ga_len != 0
+ || win->w_s->b_syn_clusters.ga_len != 0
+ || win->w_s->b_keywtab.ht_used > 0
+ || win->w_s->b_keywtab_ic.ht_used > 0);
}
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
@@ -6124,11 +6289,22 @@ syn_get_id(wp, lnum, col, trans, spellp, keep_state)
|| col < current_col)
syntax_start(wp, lnum);
- (void)get_syntax_attr(col, spellp, keep_state);
+ (void)get_syntax_attr(col, NULL, spellp, keep_state);
return (trans ? current_trans_id : current_id);
}
+#if defined(FEAT_CONCEAL) || defined(PROTO)
+/*
+ * Return conceal substitution character
+ */
+ int
+syn_get_sub_char()
+{
+ return current_sub_char;
+}
+#endif
+
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* Return the syntax ID at position "i" in the current stack.
@@ -6164,7 +6340,7 @@ syn_get_foldlevel(wp, lnum)
int i;
/* Return quickly when there are no fold items at all. */
- if (wp->w_buffer->b_syn_folditems != 0)
+ if (wp->w_s->b_syn_folditems != 0)
{
syntax_start(wp, lnum);
@@ -6316,6 +6492,10 @@ static char *(highlight_init_light[]) =
CENT("CursorLine term=underline cterm=underline",
"CursorLine term=underline cterm=underline guibg=Grey90"),
#endif
+#ifdef FEAT_CONCEAL
+ CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey",
+ "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"),
+#endif
#ifdef FEAT_AUTOCMD
CENT("MatchParen term=reverse ctermbg=Cyan",
"MatchParen term=reverse ctermbg=Cyan guibg=Cyan"),
@@ -6400,6 +6580,10 @@ static char *(highlight_init_dark[]) =
CENT("MatchParen term=reverse ctermbg=DarkCyan",
"MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"),
#endif
+#ifdef FEAT_CONCEAL
+ CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey",
+ "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"),
+#endif
#ifdef FEAT_GUI
"Normal gui=NONE",
#endif