From 467ee8710ebc75826c3022f1f3b628f70d99e580 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sun, 11 Jun 2017 20:08:50 -0400 Subject: [PATCH] optimized syntax highlighting for *real* this time --- lib/colors.c | 34 +++++++++++++++------------------- lib/view.c | 14 +++++++++++++- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/colors.c b/lib/colors.c index 8fb27bf..cb79fff 100644 --- a/lib/colors.c +++ b/lib/colors.c @@ -67,6 +67,8 @@ static SyntaxSpan* mkspan(size_t beg, size_t end, size_t clr, SyntaxSpan* span) SyntaxSpan* colors_scan(SyntaxDef* syntax, SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) { SyntaxSpan* firstspan = spans; + SyntaxSpan* currspan = spans; + if (!syntax) return firstspan; for (size_t off = beg; off < end; off++) { size_t start = off; @@ -75,33 +77,27 @@ SyntaxSpan* colors_scan(SyntaxDef* syntax, SyntaxSpan* spans, Buf* buf, size_t b else if (matches(buf, &off, syntax->comments.multi_beg)) for (; off < end && !matches(buf, &off, syntax->comments.multi_end); off++); if (start != off) - spans = mkspan(start, --off, CLR_Comment, spans); - if (!firstspan && spans) - firstspan = spans; + currspan = mkspan(start, --off, CLR_Comment, currspan); + if (!firstspan && currspan) + firstspan = currspan; } + return firstspan; } SyntaxSpan* colors_rewind(SyntaxSpan* spans, size_t first) { - /* rewind to the first span that start before visible space */ - while (spans && spans->beg >= first && spans->prev) - spans = spans->prev; + SyntaxSpan *curr = spans, *next = (spans ? spans->next : NULL); + while (curr && curr->end > first) + next = curr, curr = curr->prev; - /* if we're on the first one, setup to return NULL, otherwise return the - previous one because we're about to regenerate the current one and - everything after it */ - SyntaxSpan* ret = (spans ? spans->prev : NULL); + if (curr) curr->next = NULL; - /* ok now free the rest of the list */ - while (spans) { - SyntaxSpan* dead = spans; - spans = dead->next; + for (SyntaxSpan* span = next; span;) { + SyntaxSpan* dead = span; + span = dead->next; + if (span) span->prev = NULL; free(dead); } - - /* make sure we clear out the next link */ - if (ret) ret->next = NULL; - - return ret; + return curr; } diff --git a/lib/view.c b/lib/view.c index 5ee56bf..4ddff64 100644 --- a/lib/view.c +++ b/lib/view.c @@ -103,12 +103,16 @@ void view_update(View* view, size_t* csrx, size_t* csry) { view_scrollto(view, csr); /* locate the cursor if visible */ find_cursor(view, csrx, csry); + /* synchronize, scan for, and apply highlighted regions */ + if (!view->syntax) return; + size_t first = (view->nrows ? view->rows[0]->off : 0), last = buf_end(&(view->buffer)); if (view->nrows) last = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen; view->spans = colors_rewind(view->spans, first); + first = (view->spans ? view->spans->end : 0); view->spans = colors_scan(view->syntax, view->spans, &(view->buffer), first, last+1); apply_colors(view); } @@ -674,7 +678,16 @@ static void sync_line_numbers(View* view) { } static void apply_colors(View* view) { + /* fast forward the span list to the first span that ends on screen if there + is one. We take care to not go past the last item because we need to + ensure newly scanned items are poperly appended next time around */ + size_t first = (view->nrows ? view->rows[0]->off : 0); SyntaxSpan* curr = view->spans; + for (; curr && curr->next && curr->end < first; curr = curr->next); + view->spans = curr; + + /* ok, now for each row, scan the columns and apply the colors for the span + that each rune is a member of. */ for (size_t r = 0; curr && r < view->nrows; r++) { Row* row = view->rows[r]; size_t off = row->off, col = 0; @@ -693,5 +706,4 @@ static void apply_colors(View* view) { col++; } } - } -- 2.49.0