led: indenting and deindenting when auto-indent buffer is empty
[neatvi.git] / syn.c
blobfa0a1d7f87be0ad34efd83c2ce18abdf96a99017
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "vi.h"
6 #define NFTS 16
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 int syn_merge(int old, int new)
28 int fg = SYN_FGSET(new) ? SYN_FG(new) : SYN_FG(old);
29 int bg = SYN_BGSET(new) ? SYN_BG(new) : SYN_BG(old);
30 return ((old | new) & SYN_FLG) | (bg << 8) | fg;
33 void syn_context(int att)
35 syn_ctx = att;
38 int *syn_highlight(char *ft, char *s)
40 int subs[16 * 2];
41 int n = uc_slen(s);
42 int *att = malloc(n * sizeof(att[0]));
43 int sidx = 0;
44 struct rset *rs = syn_find(ft);
45 int flg = 0;
46 int hl, j, i;
47 memset(att, 0, n * sizeof(att[0]));
48 if (!rs)
49 return att;
50 for (i = 0; i < n; i++)
51 att[i] = syn_ctx;
52 while ((hl = rset_find(rs, s + sidx, LEN(subs) / 2, subs, flg)) >= 0) {
53 int grp = 0;
54 int cend = 1;
55 int *catt;
56 conf_highlight(hl, NULL, &catt, NULL, &grp);
57 for (i = 0; i < LEN(subs) / 2; i++) {
58 if (subs[i * 2] >= 0) {
59 int beg = uc_off(s, sidx + subs[i * 2 + 0]);
60 int end = uc_off(s, sidx + subs[i * 2 + 1]);
61 for (j = beg; j < end; j++)
62 att[j] = syn_merge(att[j], catt[i]);
63 if (i == grp)
64 cend = MAX(cend, subs[i * 2 + 1]);
67 sidx += cend;
68 flg = RE_NOTBOL;
70 return att;
73 static void syn_initft(char *name)
75 char *pats[128] = {NULL};
76 char *ft, *pat;
77 int i, n;
78 for (i = 0; !conf_highlight(i, &ft, NULL, &pat, NULL) && i < LEN(pats); i++)
79 if (!strcmp(ft, name))
80 pats[i] = pat;
81 n = i;
82 for (i = 0; i < LEN(ftmap); i++) {
83 if (!ftmap[i].ft[0]) {
84 strcpy(ftmap[i].ft, name);
85 ftmap[i].rs = rset_make(n, pats, 0);
86 return;
91 char *syn_filetype(char *path)
93 int hl = rset_find(syn_ftrs, path, 0, NULL, 0);
94 char *ft;
95 if (!conf_filetype(hl, &ft, NULL))
96 return ft;
97 return "";
100 void syn_init(void)
102 char *pats[128] = {NULL};
103 char *pat, *ft;
104 int i;
105 for (i = 0; !conf_highlight(i, &ft, NULL, NULL, NULL); i++)
106 if (!syn_find(ft))
107 syn_initft(ft);
108 for (i = 0; !conf_filetype(i, NULL, &pat) && i < LEN(pats); i++)
109 pats[i] = pat;
110 syn_ftrs = rset_make(i, pats, 0);
113 void syn_done(void)
115 int i;
116 for (i = 0; i < LEN(ftmap); i++)
117 if (ftmap[i].rs)
118 rset_free(ftmap[i].rs);
119 rset_free(syn_ftrs);