Implement vim keystrokes, vim modes and bar's lines

This commit is contained in:
Night Kaly 2024-07-03 09:58:51 +01:00
parent 5549a3d93e
commit 232db589e3
Signed by: night0721
GPG key ID: 957D67B8DB7A119B
5 changed files with 128 additions and 38 deletions

View file

@ -3,6 +3,7 @@
void insert_char(int c); void insert_char(int c);
void insert_new_line(); void insert_new_line();
void shift_new_line();
void del_char(); void del_char();
#endif #endif

View file

@ -10,17 +10,18 @@
#define VERSION "0.0.1" #define VERSION "0.0.1"
/* number of times of warning before quitting when there is modified text */ /* number of times of warning before quitting when there is modified text */
#define QUIT_CONFIRM 2 #define QUIT_CONFIRM 1
/* 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 SURFACE_1_BG "\x1b[38;2;49;50;68m"
#define BLACK_BG "\x1b[38;2;0;0;0m"
#define BLACK_FG "\x1b[48;2;0;0;0m" #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 WHITE_FG "\x1b[48;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 NORMAL 0 #define NORMAL 0

View file

@ -11,11 +11,20 @@ void draw_status_bar(struct abuf *ab)
{ {
abAppend(ab, "\x1b[7m", 4); abAppend(ab, "\x1b[7m", 4);
abAppend(ab, "\x1b[1m", 4); abAppend(ab, "\x1b[1m", 4);
abAppend(ab, BLUE_BG, 19);
int mode_len;
if (vip.mode == NORMAL) {
abAppend(ab, BLUE_BG, 19);
char mode[9] = " NORMAL "; char mode[9] = " NORMAL ";
int mode_len = 8;
abAppend(ab, mode, 8); abAppend(ab, mode, 8);
mode_len = 8;
} else {
abAppend(ab, GREEN_BG, 19);
char mode[9] = " INSERT ";
abAppend(ab, mode, 8);
mode_len = 8;
}
abAppend(ab, "\x1b[22m", 5); abAppend(ab, "\x1b[22m", 5);
char git_branch[80], git_diff[80], file[80], lines[80], coord[80]; char git_branch[80], git_diff[80], file[80], lines[80], coord[80];
@ -23,11 +32,20 @@ void draw_status_bar(struct abuf *ab)
int gitd_len = snprintf(git_diff, sizeof(git_diff), " %s ", "+1"); int gitd_len = snprintf(git_diff, sizeof(git_diff), " %s ", "+1");
int file_len = snprintf(file, sizeof(file), " %.20s %s", int file_len = snprintf(file, sizeof(file), " %.20s %s",
vip.filename ? vip.filename : "[No Name]", vip.dirty ? "[+]" : ""); vip.filename ? vip.filename : "[No Name]", vip.dirty ? "[+]" : "");
int lines_len = snprintf(lines, sizeof(lines), " %dL ", vip.rows); int lines_len;
if (vip.rows == 0 || vip.rows == vip.cy + 1) {
lines_len = snprintf(lines, sizeof(lines), " %s ", vip.rows == 0 ? "Top" : "Bot");
} else {
lines_len = snprintf(lines, sizeof(lines), " %d%% ", ((vip.cy + 1) * 100 / vip.rows));
}
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, 16); /* background */
if (vip.mode == NORMAL) {
abAppend(ab, BLUE_FG, 19); /* text */ abAppend(ab, BLUE_FG, 19); /* text */
} else {
abAppend(ab, GREEN_FG, 19);
}
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, 19);
@ -40,9 +58,17 @@ void draw_status_bar(struct abuf *ab)
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, 16);
if (vip.mode == NORMAL) {
abAppend(ab, BLUE_FG, 19); abAppend(ab, BLUE_FG, 19);
} else {
abAppend(ab, GREEN_FG, 19);
}
abAppend(ab, lines, lines_len); abAppend(ab, lines, lines_len);
if (vip.mode == NORMAL) {
abAppend(ab, BLUE_BG, 19); abAppend(ab, BLUE_BG, 19);
} else {
abAppend(ab, GREEN_BG, 19);
}
abAppend(ab, BLACK_FG, 13); abAppend(ab, BLACK_FG, 13);
abAppend(ab, "\x1b[1m", 4); abAppend(ab, "\x1b[1m", 4);
abAppend(ab, coord, coord_len); abAppend(ab, coord, coord_len);

View file

@ -28,6 +28,16 @@ void insert_new_line()
vip.cx = 0; vip.cx = 0;
} }
/*
* 'o' in vim
*/
void shift_new_line()
{
insert_row(vip.cy + 1, "", 0);
vip.cy++;
vip.cx = 0;
}
void del_char() void del_char()
{ {
if (vip.cy == vip.rows) return; if (vip.cy == vip.rows) return;

102
src/vip.c
View file

@ -41,10 +41,6 @@ int read_key()
die("read"); die("read");
} }
} }
if (c == 'k') return ARROW_UP;
if (c == 'j') return ARROW_DOWN;
if (c == 'l') return ARROW_RIGHT;
if (c == 'h') return ARROW_LEFT;
if (c == '\x1b') { if (c == '\x1b') {
char seq[3]; char seq[3];
@ -302,7 +298,6 @@ void move_cursor(int key)
void process_key() void process_key()
{ {
static int quit_times = QUIT_CONFIRM;
int c = read_key(); int c = read_key();
switch (c) { switch (c) {
@ -310,21 +305,6 @@ void process_key()
insert_new_line(); insert_new_line();
break; break;
case CTRL_KEY('q'):
if (vip.dirty && quit_times > 0) {
set_status_bar_message("No write since last change for buffer \"%s\"", vip.filename);
quit_times--;
return;
}
write(STDOUT_FILENO, "\x1b[2J", 4);
write(STDOUT_FILENO, "\x1b[H", 3);
exit(0);
break;
case CTRL_KEY('s'):
save_file();
break;
case HOME_KEY: case HOME_KEY:
vip.cx = 0; vip.cx = 0;
break; break;
@ -337,10 +317,12 @@ void process_key()
case BACKSPACE: case BACKSPACE:
case CTRL_KEY('h'): case CTRL_KEY('h'):
case DEL_KEY: case DEL_KEY: /* PASSTHROUGH */
if (vip.mode == INSERT) {
if (c == DEL_KEY) if (c == DEL_KEY)
move_cursor(ARROW_RIGHT); move_cursor(ARROW_RIGHT);
del_char(); del_char();
}
break; break;
case PAGE_UP: case PAGE_UP:
@ -362,18 +344,88 @@ void process_key()
case ARROW_DOWN: case ARROW_DOWN:
case ARROW_LEFT: case ARROW_LEFT:
case ARROW_RIGHT: case ARROW_RIGHT:
if (vip.mode == INSERT) {
move_cursor(c); move_cursor(c);
}
break; break;
case CTRL_KEY('l'): case CTRL_KEY('l'):
case '\x1b': case '\x1b':
if (vip.mode == INSERT) {
vip.mode = NORMAL;
move_cursor(ARROW_LEFT);
}
break; break;
default: case 'i':
insert_char(c); if (vip.mode == NORMAL) {
vip.mode = INSERT;
}
break;
case ':': /* PASSTHROUGH */
if (vip.mode == NORMAL) {
char *cmd = prompt_editor(":%s");
switch (cmd[0]) {
case 'q':
if (cmd[1] == '!') {
write(STDOUT_FILENO, "\x1b[2J", 4);
write(STDOUT_FILENO, "\x1b[H", 3);
exit(0);
break;
} else {
if (vip.dirty) {
set_status_bar_message("No write since last change for buffer \"%s\"", vip.filename);
return;
}
write(STDOUT_FILENO, "\x1b[2J", 4);
write(STDOUT_FILENO, "\x1b[H", 3);
exit(0);
break;
}
case 'w':
save_file();
}
}
case 'k': /* PASSTHROUGH */
if (vip.mode != INSERT) {
move_cursor(ARROW_UP);
break;
}
case 'j': /* PASSTHROUGH */
if (vip.mode != INSERT) {
move_cursor(ARROW_DOWN);
break;
}
case 'l': /* PASSTHROUGH */
if (vip.mode != INSERT) {
move_cursor(ARROW_RIGHT);
break;
}
case 'h': /* PASSTHROUGH */
if (vip.mode != INSERT) {
move_cursor(ARROW_LEFT);
break;
}
case 'o': /* PASSTHROUGH */
if (vip.mode == NORMAL) {
shift_new_line();
vip.mode = INSERT;
break;
}
default:
if (vip.mode == INSERT) {
insert_char(c);
}
break; break;
} }
quit_times = QUIT_CONFIRM;
} }
void init_editor() void init_editor()
@ -405,7 +457,7 @@ int main(int argc, char **argv)
open_editor(argv[1]); open_editor(argv[1]);
} }
set_status_bar_message("Ctrl-S: Save, Ctrl-Q:Quit"); set_status_bar_message(":w - Save, :q - Quit");
while (1) { while (1) {
refresh_screen(); refresh_screen();