aboutsummaryrefslogtreecommitdiff
path: root/view.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-10-18 21:19:28 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-11-08 13:37:23 +0100
commit6b45ee350eab3de652ec1e9ed6d225c67e558054 (patch)
treee9ac8b0bf866f4005e2bc3390a834967f84003d1 /view.c
parent55d22938311853415506860342511297827d00c1 (diff)
downloadvis-6b45ee350eab3de652ec1e9ed6d225c67e558054.tar.gz
vis-6b45ee350eab3de652ec1e9ed6d225c67e558054.tar.xz
vis: factor out syntax highlighting code
The view_draw function renders the text into the cells array and resyncs the cursor position. The syntax highlighting is applied in view_update, which also instructs the ui to update.
Diffstat (limited to 'view.c')
-rw-r--r--view.c105
1 files changed, 58 insertions, 47 deletions
diff --git a/view.c b/view.c
index 1a308e5..b0209c6 100644
--- a/view.c
+++ b/view.c
@@ -73,6 +73,7 @@ struct View {
Selection *selections; /* all selected regions */
lua_State *lua; /* lua state used for syntax highlighting */
char *lexer_name;
+ bool need_update; /* whether view has been redrawn */
};
static const SyntaxSymbol symbols_none[] = {
@@ -335,31 +336,18 @@ void view_cursor_to(View *view, size_t pos) {
* stop once the screen is full, update view->end, view->lastline */
void view_draw(View *view) {
view_clear(view);
- /* absolute start of visible area */
- size_t start = view->start;
- /* maximal number of bytes to consider for syntax highlighting before
- * the visible area */
- const size_t lexer_before_max = 4096;
- /* absolute position to start syntax highlighting */
- size_t lexer_start = start >= lexer_before_max ? start - lexer_before_max : 0;
- /* number of bytes used for syntax highlighting before visible are */
- size_t lexer_before = start - lexer_start;
- /* number of bytes to read in one go */
- const size_t text_size = lexer_before_max + (view->width * view->height);
+ /* read a screenful of text */
+ const size_t text_size = view->width * view->height;
/* current buffer to work with */
char text[text_size+1];
- /* remaining bytes to process in buffer*/
- size_t text_len = text_bytes_get(view->text, lexer_start, text_size, text);
+ /* remaining bytes to process in buffer */
+ size_t rem = text_bytes_get(view->text, view->start, text_size, text);
/* NUL terminate text section */
- text[text_len] = '\0';
- /* remaining bytes to process */
- size_t rem = text_len;
- if (rem >= lexer_before)
- rem -= lexer_before;
+ text[rem] = '\0';
/* absolute position of character currently being added to display */
- size_t pos = start;
+ size_t pos = view->start;
/* current position into buffer from which to interpret a character */
- char *cur = text + lexer_before;
+ char *cur = text;
/* start from known multibyte state */
mbstate_t mbstate = { 0 };
@@ -417,6 +405,53 @@ void view_draw(View *view) {
view->end = pos;
view->lastline = view->line ? view->line : view->bottomline;
+ /* clear remaining of line, important to show cursor at end of file */
+ if (view->line) {
+ for (int x = view->col; x < view->width; x++)
+ view->line->cells[x] = cell_blank;
+ }
+
+ /* resync position of cursors within visible area */
+ for (Cursor *c = view->cursors; c; c = c->next) {
+ size_t pos = view_cursors_pos(c);
+ if (view_coord_get(view, pos, &c->line, &c->row, &c->col)) {
+ c->line->cells[c->col].cursor = true;
+ if (view->ui) {
+ Line *line_match; int col_match;
+ size_t pos_match = text_bracket_match_except(view->text, pos, "<>");
+ if (pos != pos_match && view_coord_get(view, pos_match, &line_match, NULL, &col_match)) {
+ line_match->cells[col_match].selected = true;
+ }
+ }
+ } else if (c == view->cursor) {
+ c->line = view->topline;
+ c->row = 0;
+ c->col = 0;
+ }
+ }
+
+ view->need_update = true;
+}
+
+void view_update(View *view) {
+ if (!view->need_update)
+ return;
+ /* maximal number of bytes to consider for syntax highlighting before
+ * the visible area */
+ const size_t lexer_before_max = 4096;
+ /* absolute position to start syntax highlighting */
+ const size_t lexer_start = view->start >= lexer_before_max ? view->start - lexer_before_max : 0;
+ /* number of bytes used for syntax highlighting before visible are */
+ const size_t lexer_before = view->start - lexer_start;
+ /* number of bytes to read in one go */
+ const size_t text_size = lexer_before + (view->end - view->start);
+ /* current buffer to work with */
+ char text[text_size+1];
+ /* bytes to process */
+ const size_t text_len = text_bytes_get(view->text, lexer_start, text_size, text);
+ /* NUL terminate text section */
+ text[text_len] = '\0';
+
lua_State *L = view->lua;
if (L && view->lexer_name) {
@@ -433,6 +468,7 @@ void view_draw(View *view) {
const char *lex_text = text;
if (lexer_start > 0) {
/* try to start lexing at a line boundry */
+ /* TODO: start at known state, handle nested lexers */
const char *newline = memchr(text, '\n', lexer_before);
if (newline)
lex_text = newline;
@@ -477,12 +513,7 @@ void view_draw(View *view) {
lua_pop(L, 1);
}
- lua_pop(L, 3); /* _TOKENSTYLES, language specific lexer, lexers globale */
- }
-
- if (view->line) {
- for (int x = view->col; x < view->width; x++)
- view->line->cells[x] = cell_blank;
+ lua_pop(L, 3); /* _TOKENSTYLES, language specific lexer, lexers global */
}
for (Line *l = view->lastline->next; l; l = l->next) {
@@ -524,26 +555,9 @@ void view_draw(View *view) {
}
}
- for (Cursor *c = view->cursors; c; c = c->next) {
- size_t pos = view_cursors_pos(c);
- if (view_coord_get(view, pos, &c->line, &c->row, &c->col)) {
- c->line->cells[c->col].cursor = true;
- if (view->ui) {
- Line *line_match; int col_match;
- size_t pos_match = text_bracket_match_except(view->text, pos, "<>");
- if (pos != pos_match && view_coord_get(view, pos_match, &line_match, NULL, &col_match)) {
- line_match->cells[col_match].selected = true;
- }
- }
- } else if (c == view->cursor) {
- c->line = view->topline;
- c->row = 0;
- c->col = 0;
- }
- }
-
if (view->ui)
view->ui->draw(view->ui);
+ view->need_update = false;
}
bool view_resize(View *view, int width, int height) {
@@ -860,9 +874,6 @@ void view_scroll_to(View *view, size_t pos) {
view_cursors_scroll_to(view->cursor, pos);
}
-#include <stdio.h>
-
-
bool view_syntax_set(View *view, const char *name) {
if (!name) {
free(view->lexer_name);