commit ae68d34fe958c1d23b9d7a4f5a85c259773f75d2
parent 47e4d61a6d4032ad5385e4ec2b250d03b33e3ee2
Author: night0721 <[email protected]>
Date: Wed, 3 Jul 2024 13:12:41 +0100
Make colors align, add syntax highlight and command mode
Diffstat:
7 files changed, 152 insertions(+), 32 deletions(-)
diff --git a/include/syntax.h 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
@@ -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
@@ -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
@@ -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
@@ -3,6 +3,7 @@
#include <string.h>
#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
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#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
@@ -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 */