From 1330380ffbad2103ba24d80d9ee28717ae1f3620 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 12 Jun 2017 08:20:59 -0400 Subject: [PATCH] added highlighting for strings and character literals in C --- config.h | 1 + inc/edit.h | 13 +++--- lib/colors.c | 112 +++++++++++++++++++++++++++++++++------------------ 3 files changed, 82 insertions(+), 44 deletions(-) diff --git a/config.h b/config.h index e11e1ca..5f4ec4c 100644 --- a/config.h +++ b/config.h @@ -92,6 +92,7 @@ int CLR_HorBorder = 2; // Horizontal border color int CLR_VerBorder = 2; // Vertical border color int CLR_Ruler = 1; // Ruler color int CLR_Cursor = 7; // Cursor color + int CLR_CurrentLine = 13; // Current Line Number int CLR_Comment = 2; // Comment color diff --git a/inc/edit.h b/inc/edit.h index a6d959b..5e655f1 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -122,14 +122,17 @@ void binsave(Buf* buf, FILE* file); /* Syntax Highlighting *****************************************************************************/ +typedef struct { + int color; + enum { END, CONT } oneol; + char* beg; + char* end; +} SyntaxRule; + typedef struct { char* name; char** extensions; - struct { - char* line_beg; - char* multi_beg; - char* multi_end; - } comments; + SyntaxRule* rules; } SyntaxDef; typedef struct SyntaxSpan { diff --git a/lib/colors.c b/lib/colors.c index cb79fff..4af8f9c 100644 --- a/lib/colors.c +++ b/lib/colors.c @@ -3,29 +3,46 @@ #include #include +static bool matches(Buf* buf, size_t* off, char* str); +static SyntaxSpan* mkspan(size_t beg, size_t end, size_t clr, SyntaxSpan* span); + static SyntaxDef Syntaxes[] = { { .name = "Text", .extensions = (char*[]){ 0 }, - .comments = { .line_beg = "#" } + .rules = (SyntaxRule[]){ + { .oneol = END, .beg = "#" }, + {0,0,0} + } }, { .name = "C", .extensions = (char*[]){ ".c", ".h", ".C", ".cpp", ".CPP", ".hpp", ".cc", ".c++", ".cxx", 0 }, - .comments = { - .line_beg = "//", .multi_beg = "/*", .multi_end = "*/" } - }, - { - .name = "Ruby", - .extensions = (char*[]){ ".rb", 0 }, - .comments = { .line_beg = "#" } + .rules = (SyntaxRule[]){ + { .color = 14, .oneol = END, .beg = "\"", .end = "\"" }, + { .color = 14, .oneol = END, .beg = "'", .end = "'" }, + { .color = 2, .oneol = END, .beg = "//" }, + { .color = 2, .oneol = CONT, .beg = "/*", .end = "*/" }, + {0,0,0} + } + +// .comments = { +// .line_beg = "//", .multi_beg = "/*", .multi_end = "*/" } + }, - { - .name = "Shell", - .extensions = (char*[]){ ".sh", 0 }, - .comments = { .line_beg = "#" } - } + +// { +// .name = "Ruby", +// .extensions = (char*[]){ ".rb", 0 }, +// .comments = { .line_beg = "#" } +// }, +// { +// .name = "Shell", +// .extensions = (char*[]){ ".sh", 0 }, +// .comments = { .line_beg = "#" } +// } + }; SyntaxDef* colors_find(char* path) { @@ -40,29 +57,21 @@ SyntaxDef* colors_find(char* path) { return &Syntaxes[0]; } -static bool matches(Buf* buf, size_t* off, char* str) { - size_t curr = *off; - if (str) { - while (*str && *str == buf_get(buf, curr)) - curr++, str++; - if (*str == '\0') { - *off = curr; - return true; +bool apply_rule(SyntaxRule* rule, Buf* buf, size_t* off, int* color) { + bool ret = false; + size_t end = buf_end(buf); + if (matches(buf, off, rule->beg)) { + ret = true; + while (*off < end) { + if ((rule->oneol == END || !rule->end) && buf_iseol(buf, *off)) + break; + else if (matches(buf, off, rule->end)) + break; + *off = *off + 1; } + *color = rule->color; } - return false; -} - -static SyntaxSpan* mkspan(size_t beg, size_t end, size_t clr, SyntaxSpan* span) { - SyntaxSpan* newspan = malloc(sizeof(SyntaxSpan)); - newspan->beg = beg; - newspan->end = end; - newspan->color = clr; - newspan->prev = span; - newspan->next = NULL; - if (span) - span->next = newspan; - return newspan; + return ret; } SyntaxSpan* colors_scan(SyntaxDef* syntax, SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) { @@ -70,14 +79,14 @@ SyntaxSpan* colors_scan(SyntaxDef* syntax, SyntaxSpan* spans, Buf* buf, size_t b SyntaxSpan* currspan = spans; if (!syntax) return firstspan; + int color = CLR_Comment; for (size_t off = beg; off < end; off++) { size_t start = off; - if (matches(buf, &off, syntax->comments.line_beg)) - for (; off < end && !buf_iseol(buf, off); off++); - else if (matches(buf, &off, syntax->comments.multi_beg)) - for (; off < end && !matches(buf, &off, syntax->comments.multi_end); off++); + for (SyntaxRule* rules = syntax->rules; rules && rules->beg; rules++) + if (apply_rule(rules, buf, &off, &color)) + break; if (start != off) - currspan = mkspan(start, --off, CLR_Comment, currspan); + currspan = mkspan(start, --off, color, currspan); if (!firstspan && currspan) firstspan = currspan; } @@ -101,3 +110,28 @@ SyntaxSpan* colors_rewind(SyntaxSpan* spans, size_t first) { return curr; } +static bool matches(Buf* buf, size_t* off, char* str) { + size_t curr = *off; + if (str) { + while (*str && *str == buf_get(buf, curr)) + curr++, str++; + if (*str == '\0') { + *off = curr; + return true; + } + } + return false; +} + +static SyntaxSpan* mkspan(size_t beg, size_t end, size_t clr, SyntaxSpan* span) { + SyntaxSpan* newspan = malloc(sizeof(SyntaxSpan)); + newspan->beg = beg; + newspan->end = end; + newspan->color = clr; + newspan->prev = span; + newspan->next = NULL; + if (span) + span->next = newspan; + return newspan; +} + -- 2.49.0