Make colors align, add syntax highlight and command mode

This commit is contained in:
Night Kaly 2024-07-03 13:12:41 +01:00
parent 47e4d61a6d
commit ae68d34fe9
Signed by: night0721
GPG key ID: 957D67B8DB7A119B
7 changed files with 151 additions and 31 deletions

7
include/syntax.h Normal file
View file

@ -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

View file

@ -14,18 +14,22 @@
/* THEME */ /* THEME */
/* 38 and 48 is reversed as bar's color is reversed */ /* 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 COLOR_LEN 19
#define BLACK_BG "\x1b[38;2;0;0;0m"
#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_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_FG "\x1b[48;2;137;180;250m"
#define BLUE_BG "\x1b[38;2;137;180;250m" #define BLUE_BG "\x1b[38;2;137;180;250m"
#define GREEN_FG "\x1b[48;2;166;227;161m" #define GREEN_FG "\x1b[48;2;166;227;161m"
#define GREEN_BG "\x1b[38;2;166;227;161m" #define GREEN_BG "\x1b[38;2;166;227;161m"
#define PEACH_FG "\x1b[48;2;250;179;135m"
#define NORMAL 0 #define PEACH_BG "\x1b[38;2;250;179;135m"
#define INSERT 1 #define SKY_FG "\x1b[48;2;137;220;235m"
#define VISUAL 2 #define SKY_BG "\x1b[38;2;137;220;235m"
#define CTRL_KEY(k) ((k) & 0x1f) #define CTRL_KEY(k) ((k) & 0x1f)
@ -42,16 +46,31 @@ enum keys {
PAGE_DOWN PAGE_DOWN
}; };
enum modes {
NORMAL,
INSERT,
VISUAL,
COMMAND
};
enum highlight {
HL_NORMAL = 0,
HL_NUMBER,
HL_MATCH,
HL_RESET
};
typedef struct row { typedef struct row {
int size; int size;
int render_size; int render_size;
char *chars; char *chars;
char *render; char *render;
unsigned char *hl;
} row; } row;
typedef struct editor { typedef struct editor {
int cx, cy; /* chars x, y */ int cx, cy; /* chars x, y */
int rx; /* render x, y */ int rx; /* render x */
int rowoff; int rowoff;
int coloff; int coloff;
int screenrows, screencols; int screenrows, screencols;

View file

@ -14,15 +14,20 @@ void draw_status_bar(struct abuf *ab)
int mode_len; int mode_len;
if (vip.mode == NORMAL) { if (vip.mode == NORMAL) {
abAppend(ab, BLUE_BG, 19); abAppend(ab, BLUE_BG, COLOR_LEN);
char mode[9] = " NORMAL "; char mode[9] = " NORMAL ";
abAppend(ab, mode, 8); abAppend(ab, mode, 8);
mode_len = 8; mode_len = 8;
} else { } else if (vip.mode == INSERT) {
abAppend(ab, GREEN_BG, 19); abAppend(ab, GREEN_BG, COLOR_LEN);
char mode[9] = " INSERT "; char mode[9] = " INSERT ";
abAppend(ab, mode, 8); abAppend(ab, mode, 8);
mode_len = 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); 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); 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) { if (vip.mode == NORMAL) {
abAppend(ab, BLUE_FG, 19); /* text */ abAppend(ab, BLUE_FG, COLOR_LEN); /* text */
} else { } else if (vip.mode == INSERT) {
abAppend(ab, GREEN_FG, 19); 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, git_branch, gitb_len);
abAppend(ab, "|", 1); abAppend(ab, "|", 1);
abAppend(ab, GREEN_FG, 19); abAppend(ab, GREEN_FG, COLOR_LEN);
abAppend(ab, git_diff, gitd_len); abAppend(ab, git_diff, gitd_len);
abAppend(ab, BLACK_BG, 13); abAppend(ab, BLACK_BG, COLOR_LEN);
abAppend(ab, WHITE_FG, 19); abAppend(ab, WHITE_FG, COLOR_LEN);
abAppend(ab, file, file_len); abAppend(ab, file, file_len);
while (file_len < vip.screencols) { while (file_len < vip.screencols) {
if (vip.screencols - mode_len - file_len - gitb_len - gitd_len - 1 == lines_len + coord_len) { 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) { if (vip.mode == NORMAL) {
abAppend(ab, BLUE_FG, 19); abAppend(ab, BLUE_FG, COLOR_LEN);
} else { } else if (vip.mode == INSERT) {
abAppend(ab, GREEN_FG, 19); abAppend(ab, GREEN_FG, COLOR_LEN);
} else if (vip.mode == COMMAND) {
abAppend(ab, PEACH_FG, COLOR_LEN);
} }
abAppend(ab, lines, lines_len); abAppend(ab, lines, lines_len);
if (vip.mode == NORMAL) { if (vip.mode == NORMAL) {
abAppend(ab, BLUE_BG, 19); abAppend(ab, BLUE_BG, COLOR_LEN);
} else { } else if (vip.mode == INSERT) {
abAppend(ab, GREEN_BG, 19); 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, "\x1b[1m", 4);
abAppend(ab, coord, coord_len); abAppend(ab, coord, coord_len);
abAppend(ab, "\x1b[22m", 5); abAppend(ab, "\x1b[22m", 5);

View file

@ -156,6 +156,9 @@ void find_callback(char *query, int key)
vip.cy = current; vip.cy = current;
vip.cx = row_rx_to_cx(row, match - row->render); vip.cx = row_rx_to_cx(row, match - row->render);
vip.rowoff = vip.rows; 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; break;
} }
} }

View file

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include "vip.h" #include "vip.h"
#include "syntax.h"
extern editor vip; extern editor vip;
@ -54,6 +55,7 @@ void update_row(row *row)
} }
row->render[idx] = '\0'; row->render[idx] = '\0';
row->render_size = idx; row->render_size = idx;
update_highlight(row);
} }
void insert_row(int at, char *s, size_t len) 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_size = 0;
vip.row[at].render = NULL; vip.row[at].render = NULL;
vip.row[at].hl = NULL;
update_row(&vip.row[at]); update_row(&vip.row[at]);
vip.rows++; vip.rows++;
@ -80,6 +83,7 @@ void free_row(row *row)
{ {
free(row->render); free(row->render);
free(row->chars); free(row->chars);
free(row->hl);
} }
void del_row(int at) void del_row(int at)

45
src/syntax.c Normal file
View file

@ -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);
}
}

View file

@ -14,6 +14,7 @@
#include "bar.h" #include "bar.h"
#include "editor.h" #include "editor.h"
#include "row.h" #include "row.h"
#include "syntax.h"
editor vip; editor vip;
@ -159,7 +160,33 @@ void draw_rows(struct abuf *ab)
int len = vip.row[filerow].render_size - vip.coloff; int len = vip.row[filerow].render_size - vip.coloff;
if (len < 0) len = 0; if (len < 0) len = 0;
if (len > vip.screencols) len = vip.screencols; 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); abAppend(ab, "\x1b[K", 3);
@ -292,8 +319,10 @@ void process_key()
case ':': /* PASSTHROUGH */ case ':': /* PASSTHROUGH */
if (vip.mode == NORMAL) { if (vip.mode == NORMAL) {
vip.mode = COMMAND;
char *cmd = prompt_editor(":%s", NULL); char *cmd = prompt_editor(":%s", NULL);
if (cmd == NULL) { if (cmd == NULL) {
vip.mode = NORMAL;
return; return;
} }
switch (cmd[0]) { switch (cmd[0]) {
@ -306,6 +335,7 @@ void process_key()
} else { } else {
if (vip.dirty) { if (vip.dirty) {
set_status_bar_message("No write since last change for buffer \"%s\"", vip.filename); set_status_bar_message("No write since last change for buffer \"%s\"", vip.filename);
vip.mode = NORMAL;
return; return;
} }
write(STDOUT_FILENO, "\x1b[2J", 4); write(STDOUT_FILENO, "\x1b[2J", 4);
@ -316,6 +346,7 @@ void process_key()
} }
case 'w': case 'w':
save_file(); save_file();
vip.mode = NORMAL;
} }
} }
case '/': /* PASSTHROUGH */ case '/': /* PASSTHROUGH */