Introduction
Introduction Statistics Contact Development Disclaimer Help
tsyn: syntax highlighting - neatvi - [fork] simple vi-type editor with UTF-8 su…
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
commit 71b2ab030dbda59b9d8cf44fb78bc0ff4af93073
parent 26f00e91254bf63cbd7a6e0bc966c158be004aea
Author: Ali Gholami Rudi <[email protected]>
Date: Fri, 22 May 2015 09:51:43 +0430
syn: syntax highlighting
Diffstat:
M Makefile | 3 ++-
M conf.c | 29 ++++++++++++++++++++++++++++-
M conf.h | 30 ++++++++++++++++++++++++++++++
M ex.c | 2 ++
M led.c | 8 ++++++++
A syn.c | 98 +++++++++++++++++++++++++++++…
M term.c | 30 ++++++++++++++++++++++++++++++
M vi.c | 2 ++
M vi.h | 17 +++++++++++++++++
9 files changed, 217 insertions(+), 2 deletions(-)
---
diff --git a/Makefile b/Makefile
t@@ -2,7 +2,8 @@ CC = cc
CFLAGS = -Wall -O2
LDFLAGS =
-OBJS = vi.o ex.o lbuf.o sbuf.o ren.o dir.o reg.o led.o uc.o term.o rset.o cmd.…
+OBJS = vi.o ex.o lbuf.o sbuf.o ren.o dir.o syn.o reg.o led.o \
+ uc.o term.o rset.o cmd.o conf.o
all: vi
diff --git a/conf.c b/conf.c
t@@ -1,5 +1,6 @@
-#include "conf.h"
+#include <stdio.h>
#include "vi.h"
+#include "conf.h"
char *conf_kmapalt(void)
{
t@@ -44,3 +45,29 @@ int conf_placeholder(int idx, char **s, char **d, int *wid)
*wid = placeholders[idx].wid;
return 0;
}
+
+int conf_highlight(int idx, char **ft, int *att, int *grp, char **pat)
+{
+ if (idx < 0 || idx >= LEN(highlights))
+ return 1;
+ if (ft)
+ *ft = highlights[idx].ft;
+ if (att)
+ *att = highlights[idx].att;
+ if (grp)
+ *grp = highlights[idx].grp;
+ if (pat)
+ *pat = highlights[idx].pat;
+ return 0;
+}
+
+int conf_filetype(int idx, char **ft, char **pat)
+{
+ if (idx < 0 || idx >= LEN(filetypes))
+ return 1;
+ if (ft)
+ *ft = filetypes[idx].ft;
+ if (pat)
+ *pat = filetypes[idx].pat;
+ return 0;
+}
diff --git a/conf.h b/conf.h
t@@ -49,3 +49,33 @@ static struct placeholder {
{"َ", "ـَ", 1},
{"ّ", "ـّ", 1},
};
+
+/* 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 */
+ char *pat; /* regular expression */
+} highlights[] = {
+ {"c", 5, 0, "\\<(char|short|int|long|float|double|void|struct|enum|uni…
+ {"c", 5, 0, "\\<(static|extern|register)\\>"},
+ {"c", 5, 0, "\\<(return|for|while|if|else|do|sizeof|goto|switch|case|d…
+ {"c", SYN_IT | 2, 0, "//.*$"},
+ {"c", SYN_IT | 2, 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, "'([^\\]|\\\\.)'"},
+
+ {"tr", SYN_BD, 0, "^\\.SH.*$"},
+ {"tr", 4, 0, "^\\.[a-zA-Z0-9]{2}.*$"},
+};
+
+/* map file names to file types */
+static struct filetype {
+ char *ft; /* file type */
+ char *pat; /* file name pattern */
+} filetypes[] = {
+ {"c", "\\.[hc]$"},
+ {"tr", "\\.(ms|tr|roff)$"},
+};
diff --git a/ex.c b/ex.c
t@@ -11,6 +11,7 @@
char xpath[PATHLEN]; /* current file */
char xpath_alt[PATHLEN]; /* alternate file */
+char xft[32]; /* filetype */
int xquit; /* exit if set */
int xvis; /* visual mode */
int xai = 1; /* autoindent option */
t@@ -189,6 +190,7 @@ static void ec_edit(char *ec)
xrow_alt = xrow;
xrow = xvis ? 0 : 1 << 20;
}
+ strcpy(xft, syn_filetype(xpath));
fd = open(xpath, O_RDONLY);
lbuf_rm(xb, 0, lbuf_len(xb));
if (fd >= 0) {
diff --git a/led.c b/led.c
t@@ -45,7 +45,9 @@ static char *led_render(char *s0)
int n, maxcol = 0;
int *pos; /* pos[i]: the screen position of the i-th character …
int *off; /* off[i]: the character at screen position i */
+ int *att; /* att[i]: the attributes of i-th character */
char **chrs; /* chrs[i]: the i-th character in s1 */
+ int att_old = 0;
struct sbuf *out;
int i, j;
int ctx = dir_context(s0);
t@@ -64,10 +66,14 @@ static char *led_render(char *s0)
}
}
}
+ att = syn_highlight(xft, s0);
out = sbuf_make();
i = 0;
while (i <= maxcol) {
int o = off[i];
+ int att_new = o >= 0 ? att[o] : 0;
+ sbuf_str(out, term_att(att_new, att_old));
+ att_old = att_new;
if (o >= 0) {
if (ren_translate(chrs[o], s0))
sbuf_str(out, ren_translate(chrs[o], s0));
t@@ -83,6 +89,8 @@ static char *led_render(char *s0)
i++;
}
}
+ sbuf_str(out, term_att(0, att_old));
+ free(att);
free(pos);
free(off);
free(chrs);
diff --git a/syn.c b/syn.c
t@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "vi.h"
+
+#define NFTS 16
+
+/* mapping filetypes to regular expression sets */
+static struct ftmap {
+ char ft[32];
+ struct rset *rs;
+} ftmap[NFTS];
+
+static struct rset *syn_ftrs;
+
+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;
+}
+
+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;
+ 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;
+ flg = RE_NOTBOL;
+ }
+ return att;
+}
+
+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)…
+ 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;
+ }
+ }
+}
+
+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, *ft;
+ int i;
+ for (i = 0; !conf_highlight(i, &ft, NULL, NULL, NULL); i++)
+ if (!syn_find(ft))
+ syn_initft(ft);
+ 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);
+}
diff --git a/term.c b/term.c
t@@ -113,3 +113,33 @@ int term_read(int ms)
return -1;
return (unsigned char) b;
}
+
+/* return a static string that changes text attributes from old to att */
+char *term_att(int att, int old)
+{
+ static char buf[128];
+ char *s = buf;
+ int fg = SYN_FG(att);
+ int bg = SYN_BG(att);
+ if (att == old)
+ return "";
+ s += sprintf(s, "\33[m\33[");
+ if (fg & SYN_BD)
+ s += sprintf(s, "1;");
+ if (fg & SYN_IT)
+ s += sprintf(s, "3;");
+ else if (fg & SYN_RV)
+ s += sprintf(s, "7;");
+ if ((fg & 0xff) < 8)
+ s += sprintf(s, "%d;", 30 + (fg & 0xff));
+ else
+ s += sprintf(s, "38;5;%d;", (fg & 0xff));
+ if (bg) {
+ if ((bg & 0xff) < 8)
+ s += sprintf(s, "%d;", 40 + (bg & 0xff));
+ else
+ s += sprintf(s, "48;5;%d;", (bg & 0xff));
+ }
+ s += sprintf(s, "m");
+ return buf;
+}
diff --git a/vi.c b/vi.c
t@@ -1227,6 +1227,7 @@ int main(int argc, char *argv[])
xvis = 1;
}
dir_init();
+ syn_init();
if (i < argc) {
snprintf(ecmd, PATHLEN, "e %s", argv[i]);
ex_command(ecmd);
t@@ -1237,6 +1238,7 @@ int main(int argc, char *argv[])
ex();
lbuf_free(xb);
reg_done();
+ syn_done();
dir_done();
return 0;
}
diff --git a/vi.h b/vi.h
t@@ -103,6 +103,7 @@ int term_cols(void);
int term_read(int timeout);
void term_record(void);
void term_commit(void);
+char *term_att(int att, int old);
#define TK_CTL(x) ((x) & 037)
#define TK_INT(c) ((c) < 0 || (c) == TK_ESC || (c) == TK_CTL('c'))
t@@ -124,11 +125,26 @@ void ex_show(char *msg);
/* process management */
char *cmd_pipe(char *cmd, char *s);
+/* syntax highlighting */
+#define SYN_BD 0x100
+#define SYN_IT 0x200
+#define SYN_RV 0x400
+#define SYN_ATTR(f, b) (((b) << 16) | (f))
+#define SYN_FG(a) ((a) & 0xffff)
+#define SYN_BG(a) ((a) >> 16)
+
+int *syn_highlight(char *ft, char *s);
+char *syn_filetype(char *path);
+void syn_init(void);
+void syn_done(void);
+
/* configuration variables */
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_filetype(int idx, char **ft, char **pat);
/* global variables */
#define PATHLEN 512
t@@ -148,3 +164,4 @@ extern int xai;
extern int xdir;
extern int xshape;
extern int xorder;
+extern char xft[];
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.