From b05771bc75d4c11837084e19dca0bf2f0f634202 Mon Sep 17 00:00:00 2001 From: sloumdrone Date: Tue, 31 Dec 2019 15:54:43 -0800 Subject: [PATCH] Adds syntax highlighting and more vim controls --- config.h | 6 +- csedit | Bin 27576 -> 28120 bytes csedit.c | 319 +++++++++++++++++++++++++++++++++++++++++++------- filetypesdb.h | 10 ++ test.txt | 3 - 5 files changed, 291 insertions(+), 47 deletions(-) create mode 100644 filetypesdb.h delete mode 100644 test.txt diff --git a/config.h b/config.h index a50047e..5d0f04b 100644 --- a/config.h +++ b/config.h @@ -1,5 +1,9 @@ -static const int tabwidth = 4; #define UNSAVED_QUIT_COUNT 1 + +static const int tabwidth = 4; + +static const int HL_NUMBER_COLOR = 31; +static const int HL_DEFAULT_COLOR = 37; diff --git a/csedit b/csedit index b767356dbe7ed640b7d0f8d474041654d73e8237..531bcc8a4d65f1b878a989177b473d11df5d887d 100755 GIT binary patch literal 28120 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 literal 27576 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 Q>2Iy%5@)5LfbshO1B4=*9smFU diff --git a/csedit.c b/csedit.c index aaec4c6..a76a382 100644 --- a/csedit.c +++ b/csedit.c @@ -24,12 +24,19 @@ // ----------- #define CSEDIT_VERSION "0.0.1" #define CTRL_KEY(k) ((k) & 0x1f) +#define HL_HIGHLIGHT_NUMBERS (1<<0) // // definitions for config file // --------------------------- enum editorMode {CommandMode, InputMode, VisualMode}; + +enum editorHighlight { + HL_NORMAL, + HL_NUMBER +}; + enum editorKey { BACKSPACE = 127, ARROW_LEFT = 1000, @@ -52,6 +59,7 @@ typedef struct erow { int rendersize; char *chars; char *render; + unsigned char *hl; } erow; struct editorConfig { @@ -68,10 +76,33 @@ struct editorConfig { char statusmsg[80]; time_t statusmsg_time; struct termios orig_termios; + struct editorSyntax *syntax; +}; + +struct editorSyntax { + char *filetype; + char **filematch; + int flags; }; 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 // ---------- @@ -194,6 +225,68 @@ int getWindowSize(int *rows, int *cols) { return 0; } +// +// syntax highlighting +// ------------------- +int is_separator(int c) { + return isspace(c) || c == '\0' || strchr(",.()+-/*=~%<>[];", c) != NULL; +} + +void editorUpdateSyntax(erow *row) { + row->hl = realloc(row->hl, row->rendersize); + memset(row->hl, HL_NORMAL, row->rendersize); + + if (E.syntax == NULL) return; + + int prev_sep = 1; + + int i; + while (i < row->size) { + char c = row->render[i]; + unsigned char prev_hl = (i > 0) ? row->hl[i - 1] : HL_NORMAL; + + if (E.syntax->flags & HL_HIGHLIGHT_NUMBERS) { + 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); + i++; + } +} + +int editorSyntaxToColor(int hl) { + switch (hl) { + case HL_NUMBER: return HL_NUMBER_COLOR; + default: return HL_DEFAULT_COLOR; + } +} + +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; + return; + } + i++; + } + } +} + // // row ops // ------- @@ -228,6 +321,8 @@ void editorUpdateRow(erow *row) { } row->render[idx] = '\0'; row->rendersize = idx; + + editorUpdateSyntax(row); } void editorInsertRow(int at, char *s, size_t len) { @@ -243,6 +338,7 @@ void editorInsertRow(int at, char *s, size_t len) { E.row[at].rendersize = 0; E.row[at].render = NULL; + E.row[at].hl = NULL; editorUpdateRow(&E.row[at]); E.numRows++; @@ -252,6 +348,7 @@ void editorInsertRow(int at, char *s, size_t len) { void editorFreeRow(erow *row) { free(row->render); free(row->chars); + free(row->hl); } void editorDelRow(int at) { @@ -357,6 +454,8 @@ void editorOpen(char *filename) { free(E.filename); E.filename = strdup(filename); + editorSelectSyntaxHighlight(); + FILE *fp = fopen(filename, "r"); if (!fp) die("Open file"); @@ -374,14 +473,15 @@ void editorOpen(char *filename) { E.unsaved = 0; } -void editorSave() { - if (E.filename == NULL) { +void editorSave(int saveAs) { + if (E.filename == NULL || saveAs) { E.filename = editorPrompt("Save as: %s"); if (E.filename == NULL) { E.filename = NULL; editorStatusMessage("Save cancelled"); return; } + editorSelectSyntaxHighlight(); } int len; @@ -473,7 +573,29 @@ void editorDrawRows(struct abuf *ab) { int len = E.row[filerow].rendersize - E.coloff; if (len < 0) len = 0; if (len > E.screenCols) len = E.screenCols; - abAppend(ab, &E.row[filerow].render[E.coloff], len); + char *c = &E.row[filerow].render[E.coloff]; + int current_color = -1; + unsigned char *hl = &E.row[filerow].hl[E.coloff]; + int j; + for (j = 0; j < len; j++) { + if (hl[j] == HL_NORMAL) { + if (current_color != -1) { + abAppend(ab, "\033[39m", 5); + current_color = -1; + } + abAppend(ab, &c[j], 1); + } else { + int color = editorSyntaxToColor(hl[j]); + if (color != current_color) { + current_color = color; + char buf[16]; + int clen = snprintf(buf, sizeof(buf), "\033[%dm", color); + abAppend(ab, buf, clen); + } + abAppend(ab, &c[j], 1); + } + } + abAppend(ab, "\033[39m", 5); } abAppend(ab, "\033[K", 3); @@ -500,8 +622,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.unsaved ? "(modified)" : ""); - int rlen = snprintf(rstatus, sizeof(rstatus), "%d:%d/%d [%c]", - E.cx, E.cy + 1, E.numRows, editorMode); + int rlen = snprintf(rstatus, sizeof(rstatus), "<%s> %d:%d/%d [%c] ", + E.syntax ? E.syntax->filetype : "generic" ,E.cx, E.cy + 1, E.numRows, editorMode); if (len > E.screenCols) len = E.screenCols; abAppend(ab, status, len); while (len < E.screenCols) { @@ -558,7 +680,7 @@ void editorPrevWord() { int x = E.cx; int y = E.cy; int moved = 0; - erow *row = (y >= E.numRows) ? NULL : &E.row[y]; + erow *row = (y >= E.numRows || y < 0) ? NULL : &E.row[y]; while (row) { if (moved && row->chars[x] != ' ' && row->chars[x] != '\t' && (x == 0 || row->chars[x - 1] == ' ' || row->chars[x - 1] == '\t')) { @@ -568,7 +690,7 @@ void editorPrevWord() { break; } else if (x == 0) { y--; - row = (y <= 0) ? NULL : &E.row[y]; + row = (y >= E.numRows || y < 0) ? NULL : &E.row[y]; if (!row) return; x = row->size; moved++; @@ -583,7 +705,7 @@ void editorNextWord() { int ws = 0; int x = E.cx; int y = E.cy; - erow *row = (y >= E.numRows) ? NULL : &E.row[y]; + erow *row = (y >= E.numRows || y < 0) ? NULL : &E.row[y]; while (row) { if (ws > 0 && row->chars[x] != ' ' && row->chars[x] != '\t') { @@ -597,7 +719,7 @@ void editorNextWord() { y++; x = 0; ws++; - row = (y >= E.numRows) ? NULL : &E.row[y]; + row = (y >= E.numRows || y < 0) ? NULL : &E.row[y]; if (!row) return; } else { x++; @@ -685,9 +807,12 @@ void editorMoveCursor(int key) { break; case 'l': case ARROW_RIGHT: - if (row && E.cx < row->size) - E.cx++; - break; + { + int mod = E.mode == CommandMode ? 1 : 0; + if (row && E.cx < row->size - mod) + E.cx++; + break; + } } row = (E.cy >= E.numRows) ? NULL : &E.row[E.cy]; @@ -727,6 +852,7 @@ void editorInputKp(int c) { switch (c) { case '\033': case CTRL_KEY('l'): + if (E.cx == E.row[E.cy].size) editorMoveCursor(ARROW_LEFT); E.mode = CommandMode; break; case '\r': @@ -745,12 +871,18 @@ void editorInputKp(int c) { } void editorCommandKp(int c) { + static int deleting = 0; + static int counter = 1; + static int place = 1; switch (c) { case 'j': case 'k': case 'h': case 'l': - editorMoveCursor(c); + while (counter > 0) { + editorMoveCursor(c); + counter--; + } break; case 'g': E.cy = 0; @@ -765,48 +897,144 @@ void editorCommandKp(int c) { break; case 'o': editorCommandKp('$'); - editorInsertNewline(); editorCommandKp('i'); + editorMoveCursor(ARROW_RIGHT); + editorInsertNewline(); break; case 'O': - editorCommandKp('0'); + editorCommandKp('^'); editorInsertNewline(); editorMoveCursor(ARROW_UP); editorCommandKp('i'); break; case 'x': - editorMoveCursor(ARROW_RIGHT); - editorDeleteChar(); + while (counter > 0) { + E.mode = InputMode; + editorMoveCursor(ARROW_RIGHT); + E.mode = CommandMode; + editorDeleteChar(); + if (E.cx == E.row[E.cy].size) editorMoveCursor(ARROW_LEFT); + } break; case 'i': case 'a': - if (c == 'a') editorMoveCursor('l'); E.mode = InputMode; - break; - case 'u': - editorPageCursor(PAGE_UP); + if (c == 'a') editorMoveCursor('l'); break; case 'd': - editorPageCursor(PAGE_DOWN); - break; + if (!deleting) { + deleting++; + return; + } else { + while (counter > 0) { + editorDelRow(E.cy); + if (E.cy == E.numRows) E.cy--; + if (E.cy < 0) E.cy = 0; + counter--; + } + break; + } case '$': - if (E.cy < E.numRows) - E.cx = E.row[E.cy].size; + if (deleting) { + int diff = E.row[E.cy].size - E.cx; + E.cx = E.row[E.cy].size - 1; + if (E.cx < 0) E.cx = 0; + while (diff > 0) { + E.mode = InputMode; + editorMoveCursor(ARROW_RIGHT); + E.mode = CommandMode; + editorDeleteChar(); + if (E.cx == E.row[E.cy].size) editorMoveCursor(ARROW_LEFT); + diff--; + } + } else if (E.cy < E.numRows) { + E.cx = E.row[E.cy].size - 1; + if (E.cx < 0) E.cx = 0; + } break; case 'w': - editorNextWord(); + while (counter > 0) { + counter--; + if (deleting) { + int orig = E.cx; + editorNextWord(); + int diff = E.cx - orig; + if (diff < 0) { + editorPrevWord(); + editorEndOfWord(); + editorMoveCursor(ARROW_RIGHT); + diff = E.cx - orig; + } + while (diff > 0) { + editorDeleteChar(); + diff--; + } + } else { + editorNextWord(); + } + } break; case 'b': - editorPrevWord(); + while (counter > 0) { + if (deleting) { + // TODO + } else { + editorPrevWord(); + } + counter--; + } break; case 'e': - editorEndOfWord(); + while (counter > 0) { + if (deleting) { + // TODO + } else { + editorEndOfWord(); + } + counter--; + } + break; + case '^': + if (deleting) { + while (E.cx > 0) { + editorDeleteChar(); + } + } else { + E.cx = 0; + } break; case '0': - case '^': - E.cx = 0; - break; + if (counter == 1) { + if (deleting) { + while (E.cx > 0) { + editorDeleteChar(); + } + } else { + E.cx = 0; + } + break; + } + /* fall through */ + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + if (counter <= 1 && place == 1) counter--; + int num = c - 48; + counter += num * place; + place *= 10; + } + return; } + deleting = 0; + place = 1; + counter = 1; } void editorProcessKeypress() { @@ -838,7 +1066,10 @@ void editorProcessKeypress() { editorPageCursor(PAGE_DOWN); return; case CTRL_KEY('s'): - editorSave(); + editorSave(0); + return; + case CTRL_KEY('a'): + editorSave(1); return; case HOME_KEY: E.cx = 0; @@ -862,18 +1093,20 @@ void editorProcessKeypress() { // init // ---- void initEditor() { - E.mode = CommandMode; - E.rowoff = 0; - E.coloff = 0; - E.numRows = 0; - E.unsaved = 0; - E.row = NULL; - E.filename = NULL; - E.statusmsg[0] = '\0'; + E.mode = CommandMode; + E.rowoff = 0; + E.coloff = 0; + E.numRows = 0; + E.unsaved = 0; E.statusmsg_time = 0; - E.cx = 0; - E.cy = 0; - E.rx = 0; + E.cx = 0; + E.cy = 0; + E.rx = 0; + E.row = NULL; + E.filename = NULL; + E.syntax = NULL; + E.statusmsg[0] = '\0'; + if (getWindowSize(&E.screenRows, &E.screenCols) == -1) die("getWindowSize"); E.screenRows -= 2; } diff --git a/filetypesdb.h b/filetypesdb.h new file mode 100644 index 0000000..3532b03 --- /dev/null +++ b/filetypesdb.h @@ -0,0 +1,10 @@ +// File extensions by language +char *C_HL_extensions[] = {".c", ".h", ".cpp", NULL}; + +struct editorSyntax HLDB[] { + { + "c", + C_HL_extensions, + HL_HIGHLIGHT_NUMBERS + } +} diff --git a/test.txt b/test.txt deleted file mode 100644 index 6de1fe6..0000000 --- a/test.txt +++ /dev/null @@ -1,3 +0,0 @@ -Hello, world! - typing. -and such.