vi: update the dimensions of a single window when the terminal is resized
[neatvi.git] / syn.c
blob5e48a547b5df210f1b5cea579e52e20c90682a44
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "vi.h"
6 #define NFTS 32
8 /* mapping filetypes to regular expression sets */
9 static struct ftmap {
10 char ft[32];
11 struct rset *rs;
12 } ftmap[NFTS];
14 static struct rset *syn_ftrs;
15 static int syn_ctx;
17 static struct rset *syn_find(char *ft)
19 int i;
20 for (i = 0; i < LEN(ftmap); i++)
21 if (!strcmp(ft, ftmap[i].ft))
22 return ftmap[i].rs;
23 return NULL;
26 static struct rset *syn_make(char *name)
28 char *pats[256] = {NULL};
29 char *ft, *pat;
30 int i;
31 int n = 0;
32 if (name == NULL || !name[0])
33 return NULL;
34 for (i = 0; !conf_highlight(i, &ft, NULL, &pat, NULL) && i < LEN(pats); i++)
35 if (!strcmp(ft, name))
36 pats[i] = pat;
37 n = i;
38 for (i = 0; i < LEN(ftmap); i++) {
39 if (!ftmap[i].ft[0]) {
40 strcpy(ftmap[i].ft, name);
41 ftmap[i].rs = rset_make(n, pats, 0);
42 return ftmap[i].rs;
45 return NULL;
48 int syn_merge(int old, int new)
50 int fg = SYN_FGSET(new) ? SYN_FG(new) : SYN_FG(old);
51 int bg = SYN_BGSET(new) ? SYN_BG(new) : SYN_BG(old);
52 return ((old | new) & SYN_FLG) | (bg << 8) | fg;
55 void syn_context(int att)
57 syn_ctx = att;
60 int *syn_highlight(char *ft, char *s)
62 int subs[16 * 2];
63 int n = uc_slen(s);
64 int *att = malloc(n * sizeof(att[0]));
65 int sidx = 0;
66 struct rset *rs = syn_find(ft);
67 int flg = 0;
68 int hl, j, i;
69 memset(att, 0, n * sizeof(att[0]));
70 if (!strcmp(ft, "___")) {
71 for (i = 0; i < n; i++)
72 att[i] = SYN_RV;
73 return att;
75 if (rs == NULL)
76 rs = syn_make(ft);
77 if (!rs)
78 return att;
79 while ((hl = rset_find(rs, s + sidx, LEN(subs) / 2, subs, flg)) >= 0) {
80 int grp = 0;
81 int cend = 1;
82 int *catt;
83 conf_highlight(hl, NULL, &catt, NULL, &grp);
84 for (i = 0; i < LEN(subs) / 2; i++) {
85 if (subs[i * 2] >= 0) {
86 int beg = uc_off(s, sidx + subs[i * 2 + 0]);
87 int end = uc_off(s, sidx + subs[i * 2 + 1]);
88 for (j = beg; j < end; j++)
89 att[j] = syn_merge(att[j], catt[i]);
90 if (i == grp)
91 cend = MAX(cend, subs[i * 2 + 1]);
94 sidx += cend;
95 flg = RE_NOTBOL;
97 for (i = 0; i < n; i++)
98 att[i] = syn_merge(att[i], syn_ctx);
99 return att;
102 char *syn_filetype(char *path)
104 int hl = rset_find(syn_ftrs, path, 0, NULL, 0);
105 char *ft;
106 if (!conf_filetype(hl, &ft, NULL))
107 return ft;
108 return "";
111 void syn_init(void)
113 char *pats[128] = {NULL};
114 char *pat;
115 int i;
116 for (i = 0; !conf_filetype(i, NULL, &pat) && i < LEN(pats); i++)
117 pats[i] = pat;
118 syn_ftrs = rset_make(i, pats, 0);
121 void syn_done(void)
123 int i;
124 for (i = 0; i < LEN(ftmap); i++)
125 if (ftmap[i].rs)
126 rset_free(ftmap[i].rs);
127 rset_free(syn_ftrs);