Proper handling of multi-line comments and end of tutorial

This commit is contained in:
Timothy Warren 2019-08-21 09:12:38 -04:00
parent 85335749fa
commit 60e4d3ab68

31
kilo.c
View File

@ -71,11 +71,13 @@ struct editorSyntax {
* Struct representing a row in the editor * Struct representing a row in the editor
*/ */
typedef struct erow { typedef struct erow {
int idx; // Row number in the file
int size; // Number of characters int size; // Number of characters
int rsize; // Number of characters rendered to screen int rsize; // Number of characters rendered to screen
char *chars; // Input characters char *chars; // Input characters
char *render; // Display characters char *render; // Display characters
unsigned char *hl; // Highlighted representation of characters unsigned char *hl; // Highlighted representation of characters
int hl_open_comment; // Is this row part of a multiline comment?
} erow; } erow;
/** /**
@ -340,7 +342,7 @@ void editorUpdateSyntax(erow *row)
int prev_sep = 1; int prev_sep = 1;
int in_string = 0; int in_string = 0;
int in_comment = 0; int in_comment = (row->idx > 0 && E.row[row->idx -1].hl_open_comment);
int i = 0; int i = 0;
while (i < row->rsize) while (i < row->rsize)
@ -348,7 +350,8 @@ void editorUpdateSyntax(erow *row)
char c = row->render[i]; char c = row->render[i];
unsigned char prev_hl = (i > 0) ? row->hl[i - 1] : HL_NORMAL; unsigned char prev_hl = (i > 0) ? row->hl[i - 1] : HL_NORMAL;
if (scs_len && ! in_string) // Single line comments
if (scs_len && ! in_string && ! in_comment)
{ {
if ( ! strncmp(&row->render[i], scs, scs_len)) if ( ! strncmp(&row->render[i], scs, scs_len))
{ {
@ -357,6 +360,7 @@ void editorUpdateSyntax(erow *row)
} }
} }
// Multi-line comments
if (mcs_len && mce_len && ! in_string) if (mcs_len && mce_len && ! in_string)
{ {
if (in_comment) if (in_comment)
@ -385,6 +389,7 @@ void editorUpdateSyntax(erow *row)
} }
} }
// Strings
if (E.syntax->flags & HL_HIGHLIGHT_STRINGS) if (E.syntax->flags & HL_HIGHLIGHT_STRINGS)
{ {
if (in_string) if (in_string)
@ -417,6 +422,7 @@ void editorUpdateSyntax(erow *row)
} }
} }
// Numbers
if (E.syntax->flags & HL_HIGHLIGHT_NUMBERS) if (E.syntax->flags & HL_HIGHLIGHT_NUMBERS)
{ {
if ((isdigit(c) && (prev_sep || prev_hl == HL_NUMBER)) || if ((isdigit(c) && (prev_sep || prev_hl == HL_NUMBER)) ||
@ -429,6 +435,7 @@ void editorUpdateSyntax(erow *row)
} }
} }
// Keywords
if (prev_sep) if (prev_sep)
{ {
int j; int j;
@ -459,6 +466,13 @@ void editorUpdateSyntax(erow *row)
prev_sep = is_separator(c); prev_sep = is_separator(c);
i++; i++;
} }
int changed = (row->hl_open_comment != in_comment);
row->hl_open_comment = in_comment;
if (changed && row->idx + 1 < E.numrows)
{
editorUpdateSyntax(&E.row[row->idx + 1]);
}
} }
int editorSyntaxToColor(int hl) int editorSyntaxToColor(int hl)
@ -611,6 +625,13 @@ void editorInsertRow(int at, char *s, size_t len)
E.row = realloc(E.row, sizeof(erow) * (E.numrows + 1)); E.row = realloc(E.row, sizeof(erow) * (E.numrows + 1));
memmove(&E.row[at + 1], &E.row[at], sizeof(erow) * (E.numrows - at)); memmove(&E.row[at + 1], &E.row[at], sizeof(erow) * (E.numrows - at));
// Update index of following rows on insert
for (int j = at + 1; j <= E.numrows; j++)
{
E.row[j].idx++;
}
E.row[at].idx = at;
E.row[at].size = len; E.row[at].size = len;
E.row[at].chars = malloc(len + 1); E.row[at].chars = malloc(len + 1);
@ -620,6 +641,7 @@ void editorInsertRow(int at, char *s, size_t len)
E.row[at].rsize = 0; E.row[at].rsize = 0;
E.row[at].render = NULL; E.row[at].render = NULL;
E.row[at].hl = NULL; E.row[at].hl = NULL;
E.row[at].hl_open_comment = 0;
editorUpdateRow(&E.row[at]); editorUpdateRow(&E.row[at]);
E.numrows++; E.numrows++;
@ -641,6 +663,11 @@ void editorDelRow(int at)
} }
editorFreeRow(&E.row[at]); editorFreeRow(&E.row[at]);
memmove(&E.row[at], &E.row[at + 1], sizeof(erow) * (E.numrows - at - 1)); memmove(&E.row[at], &E.row[at + 1], sizeof(erow) * (E.numrows - at - 1));
// Update index of following rows on delete
for (int j = at; j < E.numrows - 1; j++)
{
E.row[j].idx--;
}
E.numrows--; E.numrows--;
E.dirty++; E.dirty++;
} }