forked from aligrudi/neatvi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
syn.c
123 lines (112 loc) · 2.43 KB
/
syn.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vi.h"
#define NFTS 32
/* mapping filetypes to regular expression sets */
static struct ftmap {
char ft[32];
struct rset *rs;
} ftmap[NFTS];
static struct rset *syn_ftrs;
static int syn_ctx;
static struct rset *syn_find(char *ft)
{
int i;
for (i = 0; i < LEN(ftmap); i++)
if (!strcmp(ft, ftmap[i].ft))
return ftmap[i].rs;
return NULL;
}
static struct rset *syn_make(char *name)
{
char *pats[256] = {NULL};
char *ft, *pat;
int i;
int n = 0;
if (name == NULL || !name[0])
return NULL;
for (i = 0; !conf_highlight(i, &ft, NULL, &pat, NULL) && i < LEN(pats); i++)
if (!strcmp(ft, name))
pats[i] = pat;
n = i;
for (i = 0; i < LEN(ftmap); i++) {
if (!ftmap[i].ft[0]) {
strcpy(ftmap[i].ft, name);
ftmap[i].rs = rset_make(n, pats, 0);
return ftmap[i].rs;
}
}
return NULL;
}
int syn_merge(int old, int new)
{
int fg = SYN_FGSET(new) ? SYN_FG(new) : SYN_FG(old);
int bg = SYN_BGSET(new) ? SYN_BG(new) : SYN_BG(old);
return ((old | new) & SYN_FLG) | (bg << 8) | fg;
}
void syn_context(int att)
{
syn_ctx = att;
}
int *syn_highlight(char *ft, char *s)
{
int subs[16 * 2];
int n = uc_slen(s);
int *att = malloc(n * sizeof(att[0]));
int sidx = 0;
struct rset *rs = syn_find(ft);
int flg = 0;
int hl, j, i;
memset(att, 0, n * sizeof(att[0]));
if (rs == NULL)
rs = syn_make(ft);
if (!rs)
return att;
while ((hl = rset_find(rs, s + sidx, LEN(subs) / 2, subs, flg)) >= 0) {
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;
}
for (i = 0; i < n; i++)
att[i] = syn_merge(att[i], syn_ctx);
return att;
}
char *syn_filetype(char *path)
{
int hl = rset_find(syn_ftrs, path, 0, NULL, 0);
char *ft;
if (!conf_filetype(hl, &ft, NULL))
return ft;
return "";
}
void syn_init(void)
{
char *pats[128] = {NULL};
char *pat;
int i;
for (i = 0; !conf_filetype(i, NULL, &pat) && i < LEN(pats); i++)
pats[i] = pat;
syn_ftrs = rset_make(i, pats, 0);
}
void syn_done(void)
{
int i;
for (i = 0; i < LEN(ftmap); i++)
if (ftmap[i].rs)
rset_free(ftmap[i].rs);
rset_free(syn_ftrs);
}