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;
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;
}
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);
}
}
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;
col++;
}
}
-
}