]> git.mdlowis.com Git - projs/tide.git/commitdiff
added highlighting for strings and character literals in C
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 12 Jun 2017 12:20:59 +0000 (08:20 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 12 Jun 2017 12:20:59 +0000 (08:20 -0400)
config.h
inc/edit.h
lib/colors.c

index e11e1ca8b8217d520f75b41c5b94cb723bcac5a2..5f4ec4c6a8df415f9a4b57d2a334f66a5286b43d 100644 (file)
--- 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
 
index a6d959b7230295d881c4b7d5783387eab0cfce73..5e655f1654bb47dca668bc0cdc9ae7ac6fdedde5 100644 (file)
@@ -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 {
index cb79fff7628e5adecd71afb054719f3cb466a07e..4af8f9c65c7de191b907673644d62cfd38f9c58e 100644 (file)
@@ -3,29 +3,46 @@
 #include <edit.h>
 #include <config.h>
 
+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;
+}
+