diff --git a/include/syntax.h b/include/syntax.h new file mode 100644 index 0000000..499e208 --- /dev/null +++ b/include/syntax.h @@ -0,0 +1,7 @@ +#ifndef SYNTAX_H_ +#define SYNTAX_H_ + +void update_highlight(row *row); +char *syntax_to_color(int hl, size_t *len); + +#endif diff --git a/include/vip.h b/include/vip.h index 320c008..94896a3 100644 --- a/include/vip.h +++ b/include/vip.h @@ -14,18 +14,22 @@ /* THEME */ /* 38 and 48 is reversed as bar's color is reversed */ -#define SURFACE_1_BG "\x1b[38;2;49;50;68m" -#define BLACK_FG "\x1b[48;2;0;0;0m" -#define BLACK_BG "\x1b[38;2;0;0;0m" -#define WHITE_FG "\x1b[48;2;205;214;244m" -#define BLUE_FG "\x1b[48;2;137;180;250m" -#define BLUE_BG "\x1b[38;2;137;180;250m" -#define GREEN_FG "\x1b[48;2;166;227;161m" -#define GREEN_BG "\x1b[38;2;166;227;161m" -#define NORMAL 0 -#define INSERT 1 -#define VISUAL 2 +#define COLOR_LEN 19 + +#define SURFACE_1_BG "\x1b[38;2;049;050;068m" +#define BLACK_FG "\x1b[48;2;000;000;000m" +#define BLACK_BG "\x1b[38;2;000;000;000m" +#define WHITE_FG "\x1b[48;2;205;214;244m" +#define WHITE_BG "\x1b[38;2;205;214;244m" +#define BLUE_FG "\x1b[48;2;137;180;250m" +#define BLUE_BG "\x1b[38;2;137;180;250m" +#define GREEN_FG "\x1b[48;2;166;227;161m" +#define GREEN_BG "\x1b[38;2;166;227;161m" +#define PEACH_FG "\x1b[48;2;250;179;135m" +#define PEACH_BG "\x1b[38;2;250;179;135m" +#define SKY_FG "\x1b[48;2;137;220;235m" +#define SKY_BG "\x1b[38;2;137;220;235m" #define CTRL_KEY(k) ((k) & 0x1f) @@ -42,16 +46,31 @@ enum keys { PAGE_DOWN }; +enum modes { + NORMAL, + INSERT, + VISUAL, + COMMAND +}; + +enum highlight { + HL_NORMAL = 0, + HL_NUMBER, + HL_MATCH, + HL_RESET +}; + typedef struct row { int size; int render_size; char *chars; char *render; + unsigned char *hl; } row; typedef struct editor { int cx, cy; /* chars x, y */ - int rx; /* render x, y */ + int rx; /* render x */ int rowoff; int coloff; int screenrows, screencols; diff --git a/src/bar.c b/src/bar.c index b50e03d..98355c6 100644 --- a/src/bar.c +++ b/src/bar.c @@ -14,15 +14,20 @@ void draw_status_bar(struct abuf *ab) int mode_len; if (vip.mode == NORMAL) { - abAppend(ab, BLUE_BG, 19); + abAppend(ab, BLUE_BG, COLOR_LEN); char mode[9] = " NORMAL "; abAppend(ab, mode, 8); mode_len = 8; - } else { - abAppend(ab, GREEN_BG, 19); + } else if (vip.mode == INSERT) { + abAppend(ab, GREEN_BG, COLOR_LEN); char mode[9] = " INSERT "; abAppend(ab, mode, 8); mode_len = 8; + } else if (vip.mode == COMMAND) { + abAppend(ab, PEACH_BG, COLOR_LEN); + char mode[10] = " COMMAND "; + abAppend(ab, mode, 9); + mode_len = 9; } abAppend(ab, "\x1b[22m", 5); @@ -40,36 +45,42 @@ void draw_status_bar(struct abuf *ab) } int coord_len = snprintf(coord, sizeof(coord), " %d:%d ", vip.cy + 1, vip.rx + 1); - abAppend(ab, SURFACE_1_BG, 16); /* background */ + abAppend(ab, SURFACE_1_BG, COLOR_LEN); /* background */ if (vip.mode == NORMAL) { - abAppend(ab, BLUE_FG, 19); /* text */ - } else { - abAppend(ab, GREEN_FG, 19); + abAppend(ab, BLUE_FG, COLOR_LEN); /* text */ + } else if (vip.mode == INSERT) { + abAppend(ab, GREEN_FG, COLOR_LEN); + } else if (vip.mode == COMMAND) { + abAppend(ab, PEACH_FG, COLOR_LEN); } abAppend(ab, git_branch, gitb_len); abAppend(ab, "|", 1); - abAppend(ab, GREEN_FG, 19); + abAppend(ab, GREEN_FG, COLOR_LEN); abAppend(ab, git_diff, gitd_len); - abAppend(ab, BLACK_BG, 13); - abAppend(ab, WHITE_FG, 19); + abAppend(ab, BLACK_BG, COLOR_LEN); + abAppend(ab, WHITE_FG, COLOR_LEN); abAppend(ab, file, file_len); while (file_len < vip.screencols) { if (vip.screencols - mode_len - file_len - gitb_len - gitd_len - 1 == lines_len + coord_len) { - abAppend(ab, SURFACE_1_BG, 16); + abAppend(ab, SURFACE_1_BG, COLOR_LEN); if (vip.mode == NORMAL) { - abAppend(ab, BLUE_FG, 19); - } else { - abAppend(ab, GREEN_FG, 19); + abAppend(ab, BLUE_FG, COLOR_LEN); + } else if (vip.mode == INSERT) { + abAppend(ab, GREEN_FG, COLOR_LEN); + } else if (vip.mode == COMMAND) { + abAppend(ab, PEACH_FG, COLOR_LEN); } abAppend(ab, lines, lines_len); if (vip.mode == NORMAL) { - abAppend(ab, BLUE_BG, 19); - } else { - abAppend(ab, GREEN_BG, 19); + abAppend(ab, BLUE_BG, COLOR_LEN); + } else if (vip.mode == INSERT) { + abAppend(ab, GREEN_BG, COLOR_LEN); + } else if (vip.mode == COMMAND) { + abAppend(ab, PEACH_BG, COLOR_LEN); } - abAppend(ab, BLACK_FG, 13); + abAppend(ab, BLACK_FG, COLOR_LEN); abAppend(ab, "\x1b[1m", 4); abAppend(ab, coord, coord_len); abAppend(ab, "\x1b[22m", 5); diff --git a/src/editor.c b/src/editor.c index 98a1381..90ef7ef 100644 --- a/src/editor.c +++ b/src/editor.c @@ -156,6 +156,9 @@ void find_callback(char *query, int key) vip.cy = current; vip.cx = row_rx_to_cx(row, match - row->render); vip.rowoff = vip.rows; + + memset(&row->hl[match - row->render], HL_MATCH, strlen(query)); + memset(&row->hl[match - row->render + strlen(query)], HL_RESET, row->render_size - (match - row->render + strlen(query))); break; } } diff --git a/src/row.c b/src/row.c index d3d91c4..90c08b9 100644 --- a/src/row.c +++ b/src/row.c @@ -3,6 +3,7 @@ #include #include "vip.h" +#include "syntax.h" extern editor vip; @@ -54,6 +55,7 @@ void update_row(row *row) } row->render[idx] = '\0'; row->render_size = idx; + update_highlight(row); } void insert_row(int at, char *s, size_t len) @@ -70,6 +72,7 @@ void insert_row(int at, char *s, size_t len) vip.row[at].render_size = 0; vip.row[at].render = NULL; + vip.row[at].hl = NULL; update_row(&vip.row[at]); vip.rows++; @@ -80,6 +83,7 @@ void free_row(row *row) { free(row->render); free(row->chars); + free(row->hl); } void del_row(int at) diff --git a/src/syntax.c b/src/syntax.c new file mode 100644 index 0000000..f39b469 --- /dev/null +++ b/src/syntax.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +#include "vip.h" + +void update_highlight(row *row) +{ + row->hl = realloc(row->hl, row->render_size); + memset(row->hl, HL_NORMAL, row->render_size); + for (int i = 0; i < row->render_size; i++) { + if (isdigit(row->render[i])) { + row->hl[i] = HL_NUMBER; + } + } +} + +char *syntax_to_color(int hl, size_t *len) +{ + switch (hl) { + case HL_NUMBER: + *len = COLOR_LEN; + return strdup(PEACH_BG); + + case HL_MATCH:; + char *str = malloc(COLOR_LEN * 2 + 1); + snprintf(str, COLOR_LEN * 2 + 1, "%s%s", BLACK_BG, SKY_FG); + str[COLOR_LEN * 2] = '\0'; + *len = COLOR_LEN * 2; + return str; + + case HL_RESET:; + char *res = malloc(COLOR_LEN * 2 + 1); + snprintf(res, COLOR_LEN * 2 + 1, "%s%s", WHITE_BG, BLACK_FG); + res[COLOR_LEN * 2] = '\0'; + *len = COLOR_LEN * 2; + return res; + + default: + *len = COLOR_LEN; + return strdup(WHITE_BG); + } +} + diff --git a/src/vip.c b/src/vip.c index 312cb19..84e7378 100644 --- a/src/vip.c +++ b/src/vip.c @@ -14,6 +14,7 @@ #include "bar.h" #include "editor.h" #include "row.h" +#include "syntax.h" editor vip; @@ -159,7 +160,33 @@ void draw_rows(struct abuf *ab) int len = vip.row[filerow].render_size - vip.coloff; if (len < 0) len = 0; if (len > vip.screencols) len = vip.screencols; - abAppend(ab, &vip.row[filerow].render[vip.coloff], len); + char *c = &vip.row[filerow].render[vip.coloff]; + unsigned char *hl = &vip.row[filerow].hl[vip.coloff]; + + char *current_color = malloc(COLOR_LEN * 2); + for (int j = 0; j < len; j++) { + if (hl[j] == HL_NORMAL) { + if (strncmp(current_color, WHITE_BG, COLOR_LEN)) { + abAppend(ab, WHITE_BG, COLOR_LEN); + memcpy(current_color, WHITE_BG, COLOR_LEN); + } + abAppend(ab, &c[j], 1); + } else { + size_t len; + char *color = syntax_to_color(hl[j], &len); + FILE *f = fopen("/home/night/a", "a"); + fprintf(f, "len: %d\n", len); + if (strncmp(current_color, color, len)) { + fprintf(f, "color: %s\n", color); + memcpy(current_color, color, len); + abAppend(ab, color, len); + } + fclose(f); + free(color); + abAppend(ab, &c[j], 1); + } + } + abAppend(ab, WHITE_BG, COLOR_LEN); } abAppend(ab, "\x1b[K", 3); @@ -292,8 +319,10 @@ void process_key() case ':': /* PASSTHROUGH */ if (vip.mode == NORMAL) { + vip.mode = COMMAND; char *cmd = prompt_editor(":%s", NULL); if (cmd == NULL) { + vip.mode = NORMAL; return; } switch (cmd[0]) { @@ -306,6 +335,7 @@ void process_key() } else { if (vip.dirty) { set_status_bar_message("No write since last change for buffer \"%s\"", vip.filename); + vip.mode = NORMAL; return; } write(STDOUT_FILENO, "\x1b[2J", 4); @@ -316,6 +346,7 @@ void process_key() } case 'w': save_file(); + vip.mode = NORMAL; } } case '/': /* PASSTHROUGH */