diff --git a/kilo.c b/kilo.c index a8aae1b..ee3b521 100644 --- a/kilo.c +++ b/kilo.c @@ -44,8 +44,16 @@ enum editorHighlight { HL_MATCH }; +#define HL_HIGHLIGHT_NUMBERS (1<<0) + /*** data ***/ +struct editorSyntax { + char *filetype; + char **filematch; + int flags; +}; + typedef struct erow { int size; int rsize; @@ -67,11 +75,25 @@ struct editorConfig { char *filename; char statusmsg[80]; time_t statusmsg_time; + struct editorSyntax *syntax; struct termios orig_termios; }; struct editorConfig E; +/*** filetypes ***/ +char *C_HL_extensions[] = { ".c", ".h", ".cpp", NULL }; + +struct editorSyntax HLDB[] = { + { + "c", + C_HL_extensions, + HL_HIGHLIGHT_NUMBERS + }, +}; + +#define HLDB_ENTRIES (sizeof(HLDB) / sizeof(HLDB[0])) + /*** prototypes ***/ void editorSetStatusMessage(const char *fmt, ...); @@ -269,6 +291,11 @@ void editorUpdateSyntax(erow *row) row->hl = realloc(row->hl, row->rsize); memset(row->hl, HL_NORMAL, row->rsize); + if (E.syntax == NULL) + { + return; + } + int prev_sep = 1; int i = 0; @@ -277,12 +304,16 @@ void editorUpdateSyntax(erow *row) char c = row->render[i]; unsigned char prev_hl = (i > 0) ? row->hl[i - 1] : HL_NORMAL; - if (isdigit(c) && (prev_sep || prev_hl == HL_NUMBER)) + if (E.syntax->flags & HL_HIGHLIGHT_NUMBERS) { - row->hl[i] = HL_NUMBER; - i++; - prev_sep = 0; - continue; + if ((isdigit(c) && (prev_sep || prev_hl == HL_NUMBER)) || + (c == '.' && prev_hl == HL_NUMBER)) + { + row->hl[i] = HL_NUMBER; + i++; + prev_sep = 0; + continue; + } } prev_sep = is_separator(c); @@ -305,6 +336,41 @@ int editorSyntaxToColor(int hl) } } +void editorSelectSyntaxHighlight() +{ + E.syntax = NULL; + if (E.filename == NULL) + { + return; + } + + char *ext = strrchr(E.filename, '.'); + + for (unsigned int j = 0; j < HLDB_ENTRIES; j++) + { + struct editorSyntax *s = &HLDB[j]; + unsigned int i = 0; + while (s->filematch[i]) + { + int is_ext = (s->filematch[i][0] == '.'); + if ((is_ext && ext && !strcmp(ext, s->filematch[i])) || + ( ! is_ext && strstr(E.filename, s->filematch[i]))) + { + E.syntax = s; + + int filerow; + for (filerow = 0; filerow < E.numrows; filerow++) + { + editorUpdateSyntax(&E.row[filerow]); + } + + return; + } + i++; + } + } +} + /*** row operations ***/ int editorRowCxToRx(erow *row, int cx) @@ -552,6 +618,8 @@ void editorOpen(char *filename) free(E.filename); E.filename = strdup(filename); + editorSelectSyntaxHighlight(); + FILE *fp = fopen(filename, "r"); if ( ! fp) { @@ -587,6 +655,7 @@ void editorSave() editorSetStatusMessage("Save aborted"); return; } + editorSelectSyntaxHighlight(); } int len; @@ -862,8 +931,8 @@ void editorDrawStatusBar(struct abuf *ab) int len = snprintf(status, sizeof(status), "%.20s - %d lines %s", E.filename ? E.filename : "[No Name]", E.numrows, E.dirty ? "(modified)" : ""); - int rlen = snprintf(rstatus, sizeof(rstatus), "%d/%d", - E.cy + 1, E.numrows); + int rlen = snprintf(rstatus, sizeof(rstatus), "%s | %d/%d", + E.syntax ? E.syntax->filetype : "no ft", E.cy + 1, E.numrows); if (len > E.screencols) { @@ -1166,6 +1235,7 @@ void initEditor() E.filename = NULL; E.statusmsg[0] = '\0'; E.statusmsg_time = 0; + E.syntax = NULL; if (getWindowSize(&E.screenrows, &E.screencols) == -1) {