tsyn: nested and overlapping highlighting regions - neatvi - [fork] simple vi-type editor with UTF-8 support
(HTM) git clone git://src.adamsgaard.dk/neatvi
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit ba371ba7ddd6c24a7b8fd605de5143a45486cb74
(DIR) parent e3d2ac66bd83987579f970043be6e6c31b29dd19
(HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
Date: Sun, 7 Jun 2015 11:32:53 +0430
syn: nested and overlapping highlighting regions
Diffstat:
M conf.c | 6 +++---
M conf.h | 32 +++++++++++++++++--------------
M led.c | 7 -------
M syn.c | 35 ++++++++++++++++++++++---------
M vi.h | 3 ++-
5 files changed, 48 insertions(+), 35 deletions(-)
---
(DIR) diff --git a/conf.c b/conf.c
t@@ -46,7 +46,7 @@ int conf_placeholder(int idx, char **s, char **d, int *wid)
return 0;
}
-int conf_highlight(int idx, char **ft, int *att, int *grp, char **pat)
+int conf_highlight(int idx, char **ft, int **att, char **pat, int *end)
{
if (idx < 0 || idx >= LEN(highlights))
return 1;
t@@ -54,10 +54,10 @@ int conf_highlight(int idx, char **ft, int *att, int *grp, char **pat)
*ft = highlights[idx].ft;
if (att)
*att = highlights[idx].att;
- if (grp)
- *grp = highlights[idx].grp;
if (pat)
*pat = highlights[idx].pat;
+ if (end)
+ *end = highlights[idx].end;
return 0;
}
(DIR) diff --git a/conf.h b/conf.h
t@@ -56,28 +56,32 @@ static struct filetype {
char *pat; /* file name pattern */
} filetypes[] = {
{"c", "\\.[hc]$"},
- {"tr", "\\.(ms|tr|roff)$"},
+ {"tr", "\\.(ms|tr|roff|tmac)$"},
};
/* syntax highlighting patterns */
static struct highlight {
char *ft; /* the filetype of this pattern */
- int att; /* attributes of the matched region */
- int grp; /* regular expression subgroup to highlight */
+ int att[16]; /* attributes of the matched groups */
char *pat; /* regular expression */
+ int end; /* the group ending this pattern */
} highlights[] = {
- {"c", 5, 0, "\\<(signed|unsigned|char|short|int|long|float|double|void|struct|enum|union|typedef)\\>"},
- {"c", 5, 0, "\\<(static|extern|register)\\>"},
- {"c", 5, 0, "\\<(return|for|while|if|else|do|sizeof|goto|switch|case|default|break|continue)\\>"},
- {"c", 2 | SYN_IT, 0, "//.*$"},
- {"c", 2 | SYN_IT, 0, "/\\*([^*]|\\*[^/])*\\*/"},
- {"c", 6, 0, "^#[ \t]*[a-zA-Z0-9_]+"},
- {"c", SYN_BD, 1, "([a-zA-Z][a-zA-Z0-9_]+)\\("},
- {"c", 4, 0, "\"([^\"]|\\\\\")*\""},
- {"c", 4, 0, "'([^\\]|\\\\.)'"},
+ {"c", {5}, "\\<(signed|unsigned|char|short|int|long|float|double|void|struct|enum|union|typedef)\\>"},
+ {"c", {5}, "\\<(static|extern|register)\\>"},
+ {"c", {4}, "\\<(return|for|while|if|else|do|sizeof|goto|switch|case|default|break|continue)\\>"},
+ {"c", {2 | SYN_IT}, "//.*$"},
+ {"c", {2 | SYN_IT}, "/\\*([^*]|\\*[^/])*\\*/"},
+ {"c", {6}, "^#[ \t]*[a-zA-Z0-9_]+"},
+ {"c", {0, SYN_BD}, "([a-zA-Z][a-zA-Z0-9_]+)\\(", 1},
+ {"c", {4}, "\"([^\"]|\\\\\")*\""},
+ {"c", {4}, "'([^\\]|\\\\.)'"},
- {"tr", SYN_BD, 0, "^\\.SH.*$"},
- {"tr", 4, 0, "^\\.[a-zA-Z0-9]{2}.*$"},
+ {"tr", {4, 0, 5 | SYN_BD, 4 | SYN_BD, 5 | SYN_BD, 4 | SYN_BD},
+ "^[.'][ \t]*((SH.*)|(de) (.*)|([^ \t\\]{2,}))?.*$", 1},
+ {"tr", {2 | SYN_IT}, "\\\\\".*$"},
+ {"tr", {3}, "\\\\{1,2}[*$fgkmns]([^[(]|\\(..|\\[[^]]*\\])"},
+ {"tr", {3}, "\\\\([^[(*$fgkmns]|\\(..|\\[[^]]*\\])"},
+ {"tr", {3}, "\\$[^$]+\\$"},
};
/* how to hightlight text in the reverse direction */
(DIR) diff --git a/led.c b/led.c
t@@ -45,13 +45,6 @@ static int led_offdir(char **chrs, int *pos, int i)
return 0;
}
-static int syn_merge(int old, int new)
-{
- int fg = SYN_FG(new) ? SYN_FG(new) : SYN_FG(old);
- int bg = SYN_BG(new) ? SYN_BG(new) : SYN_BG(old);
- return fg | SYN_BGMK(bg);
-}
-
static void led_markrev(int n, char **chrs, int *pos, int *att)
{
int i = 0, j;
(DIR) diff --git a/syn.c b/syn.c
t@@ -22,6 +22,14 @@ static struct rset *syn_find(char *ft)
return NULL;
}
+int syn_merge(int old, int new)
+{
+ int fg = SYN_FG(new) ? SYN_FG(new) : SYN_FG(old);
+ int bg = SYN_BG(new) ? SYN_BG(new) : SYN_BG(old);
+ int flg = (old | new) & (SYN_IT | SYN_BD | SYN_RV);
+ return flg | fg | SYN_BGMK(bg);
+}
+
int *syn_highlight(char *ft, char *s)
{
int subs[16 * 2];
t@@ -30,19 +38,26 @@ int *syn_highlight(char *ft, char *s)
int sidx = 0;
struct rset *rs = syn_find(ft);
int flg = 0;
- int hl, j;
+ int hl, j, i;
memset(att, 0, n * sizeof(att[0]));
if (!rs)
return att;
while ((hl = rset_find(rs, s + sidx, LEN(subs) / 2, subs, flg)) >= 0) {
- int beg, end;
- int catt, cgrp;
- conf_highlight(hl, NULL, &catt, &cgrp, NULL);
- beg = uc_off(s, sidx + subs[cgrp * 2 + 0]);
- end = uc_off(s, sidx + subs[cgrp * 2 + 1]);
- for (j = beg; j < end; j++)
- att[j] = catt;
- sidx += subs[cgrp * 2 + 1] ? subs[cgrp * 2 + 1] : 1;
+ int grp = 0;
+ int cend = 1;
+ int *catt;
+ conf_highlight(hl, NULL, &catt, NULL, &grp);
+ for (i = 0; i < LEN(subs) / 2; i++) {
+ if (subs[i * 2] >= 0) {
+ int beg = uc_off(s, sidx + subs[i * 2 + 0]);
+ int end = uc_off(s, sidx + subs[i * 2 + 1]);
+ for (j = beg; j < end; j++)
+ att[j] = syn_merge(att[j], catt[i]);
+ if (i == grp)
+ cend = MAX(cend, subs[i * 2 + 1]);
+ }
+ }
+ sidx += cend;
flg = RE_NOTBOL;
}
return att;
t@@ -53,7 +68,7 @@ static void syn_initft(char *name)
char *pats[128] = {NULL};
char *ft, *pat;
int i, n;
- for (i = 0; !conf_highlight(i, &ft, NULL, NULL, &pat) && i < LEN(pats); i++)
+ for (i = 0; !conf_highlight(i, &ft, NULL, &pat, NULL) && i < LEN(pats); i++)
if (!strcmp(ft, name))
pats[i] = pat;
n = i;
(DIR) diff --git a/vi.h b/vi.h
t@@ -157,6 +157,7 @@ int cmd_exec(char *cmd);
int *syn_highlight(char *ft, char *s);
char *syn_filetype(char *path);
+int syn_merge(int old, int new);
void syn_init(void);
void syn_done(void);
t@@ -165,7 +166,7 @@ char *conf_kmapalt(void);
int conf_dirmark(int idx, char **pat, int *ctx, int *dir, int *grp);
int conf_dircontext(int idx, char **pat, int *ctx);
int conf_placeholder(int idx, char **s, char **d, int *wid);
-int conf_highlight(int idx, char **ft, int *att, int *grp, char **pat);
+int conf_highlight(int idx, char **ft, int **att, char **pat, int *end);
int conf_filetype(int idx, char **ft, char **pat);
int conf_highlight_revdir(int *att);