/* Syntax Highlighting
*****************************************************************************/
-typedef struct {
- int color;
- enum { END, CONT } oneol;
- char* beg;
- char* end;
-} SyntaxRule;
-
-typedef struct {
- char* name;
- char** extensions;
- SyntaxRule* rules;
-} SyntaxDef;
-
typedef struct SyntaxSpan {
size_t beg;
size_t end;
struct SyntaxSpan* next;
} SyntaxSpan;
-SyntaxDef* colors_find(char* path);
-SyntaxSpan* colors_scan(SyntaxDef* syntax, SyntaxSpan* spans, Buf* buf, size_t beg, size_t end);
+void colors_init(char* path);
+SyntaxSpan* colors_scan(SyntaxSpan* spans, Buf* buf, size_t beg, size_t end);
SyntaxSpan* colors_rewind(SyntaxSpan* spans, size_t first);
/* Screen management functions
Buf buffer; /* the buffer used to populate the view */
Sel selection; /* range of currently selected text */
size_t prev_csr; /* previous cursor location */
- SyntaxDef* syntax; /* syntax rules object */
SyntaxSpan* spans; /* list of colored regions */
} View;
#include <utf.h>
#include <edit.h>
#include <unistd.h>
+#include <ctype.h>
-int ChildIn = -1, ChildOut = -1;
-char Buffer[32768];
-char* DataBeg = Buffer;
-char* DataEnd = Buffer;
+static int ChildIn = -1, ChildOut = -1;
+static char Buffer[32768];
+static char* DataBeg = Buffer;
+static char* DataEnd = Buffer;
static SyntaxSpan* mkspan(size_t beg, size_t end, size_t clr, SyntaxSpan* span);
-static void dump_chunk(Buf* buf, size_t beg, size_t end);
+static void write_chunk(Buf* buf, size_t beg, size_t end);
+static int read_byte(void);
+static int read_num(void);
-SyntaxDef* colors_find(char* path) {
- char* ext = strrchr(path, '.');
- if (!strcmp(ext,".c") || !strcmp(ext,".h"))
- cmdspawn((char*[]){ "tide-hl", "C", NULL }, &ChildIn, &ChildOut);
- return NULL;
+void colors_init(char* path) {
+ cmdspawn((char*[]){ "tide-hl", path, NULL }, &ChildIn, &ChildOut);
}
-int read_byte(void) {
- if (DataBeg >= DataEnd) {
- DataBeg = DataEnd = Buffer;
- long nread = read(ChildOut, Buffer, sizeof(Buffer));
- if (nread <= 0) return EOF;
- DataEnd += nread;
- }
- return *(DataBeg++);
-}
-
-size_t read_num(void) {
- int c;
- size_t num = 0;
- while (isdigit(c = read_byte()))
- num = (num * 10) + (c - '0');
- return num;
-}
-
-SyntaxSpan* colors_scan(SyntaxDef* syntax, SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) {
+SyntaxSpan* colors_scan(SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) {
SyntaxSpan* firstspan = spans;
SyntaxSpan* currspan = spans;
/* if the engine died, clear all highlights and quit */
- if (ChildIn < 0)
+ if (ChildIn < 0 || !buf->path)
return colors_rewind(spans, 0);
/* commence the highlighting */
- if (buf->path && end-beg) {
- dump_chunk(buf, beg, end);
+ if (beg < end) {
+ write_chunk(buf, beg, end);
size_t b = 0, e = 0, c = 0;
do {
b = read_num();
e = read_num();
c = read_num();
- if (e > 0) {
+ if (e > 0 && c > 0) {
c = (c > 15 ? config_get_int(SynNormal + (c >> 4) - 1) : c) & 0xf;
- currspan = mkspan(beg+b, beg+e, c, currspan);
+ currspan = mkspan(beg+b, beg+e-1, c, currspan);
+ //printf("(%lu-%lu) %lu,%lu,%lu\n", beg, end, b, e, c);
}
- //printf("(%lu-%lu) %lu,%lu,%lu\n", beg, end, b, e, c);
if (!firstspan)
firstspan = currspan;
} while (e > 0);
- //printf("done\n");
- //fflush(stdout);
+ //printf("left: %lu\n", DataEnd-DataBeg);
+ //printf("done\n\n");
+ fflush(stdout);
+ DataBeg = DataEnd = Buffer;
}
return firstspan;
}
return newspan;
}
-static void dump_chunk(Buf* buf, size_t beg, size_t end) {
+static void write_chunk(Buf* buf, size_t beg, size_t end) {
size_t len = end - beg, wlen = 0;
char* wbuf = malloc(64 + len * 6u);
if (len && wbuf) {
for (size_t i = beg; i < end; i++) {
Rune r = buf_get(buf, i);
if (r == RUNE_CRLF) {
- wbuf[wlen++] = '\r';
wbuf[wlen++] = '\n';
} else if (buf->charset == BINARY) {
wbuf[wlen++] = (char)r;
wlen += utf8encode((char*)&(wbuf[wlen]), r);
}
}
- if (write(ChildIn, wbuf, wlen) < 0) {
+ long nwrite = write(ChildIn, wbuf, wlen);
+ //printf("write: %lu -> %d\n", wlen, nwrite);
+ if (nwrite < 0) {
+ //perror("write failed:");
/* child process probably died. shut everything down */
close(ChildIn), ChildIn = -1;
close(ChildOut), ChildOut = -1;
}
free(wbuf);
}
+
+static int read_byte(void) {
+ if (DataBeg >= DataEnd) {
+ DataBeg = DataEnd = Buffer;
+ long nread = read(ChildOut, Buffer, sizeof(Buffer));
+ if (nread <= 0) return EOF;
+ DataEnd += nread;
+ }
+ return *(DataBeg++);
+}
+
+static int read_num(void) {
+ int c, num = 0;
+ while (isdigit(c = read_byte()))
+ num = (num * 10) + (c - '0');
+ return num;
+}
end
def style_match(s)
- style_range($scan.pos - $scan.matched_size, $scan.pos-1, s)
+ style_range($scan.pos - $scan.matched_size, $scan.pos, s)
end
def range(start=nil, stop=nil, color=nil)
rule start do
- beg = $scan.pos-2
+ beg = $scan.pos - $scan.matched_size
if not $scan.scan_until stop
$scan.pos += $scan.rest_size
end
#-------------------------------------------------------------------------------
-Types = Set.new %w[
- bool short int long unsigned signed char size_t
- void extern static inline struct typedef
- int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t
-]
+language "C" do
+ Types = Set.new %w[
+ bool short int long unsigned signed char size_t
+ void extern static inline struct typedef union
+ int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t
+ ]
-Control = Set.new %w[
- goto break return continue asm case default if else switch while for do]
+ Control = Set.new %w[
+ goto break return continue asm case default if else switch while for do
+ ]
-language "C" do
- #match(/[0-9]+/, :Number)
range start=/\/\*/, stop=/\*\//, :Comment
match(/\/\/.*$/, :Comment)
match(/#\s*\w+/, :PreProcessor)
style_match(:Keyword)
end
end
+ match(/[+-]?[0-9]+[ulUL]*/, :Number)
end
#-------------------------------------------------------------------------------