Make colors align, add syntax highlight and command mode
This commit is contained in:
parent
47e4d61a6d
commit
ae68d34fe9
7 changed files with 151 additions and 31 deletions
7
include/syntax.h
Normal file
7
include/syntax.h
Normal 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
|
|
@ -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;
|
||||
|
|
47
src/bar.c
47
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
45
src/syntax.c
Normal file
45
src/syntax.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
33
src/vip.c
33
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 */
|
||||
|
|
Loading…
Reference in a new issue