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 */
|
/* 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 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 COLOR_LEN 19
|
||||||
#define INSERT 1
|
|
||||||
#define VISUAL 2
|
#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)
|
#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;
|
||||||
|
|
47
src/bar.c
47
src/bar.c
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
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 "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 */
|
||||||
|
|
Loading…
Reference in a new issue