Implement vim keystrokes, vim modes and bar's lines
This commit is contained in:
parent
5549a3d93e
commit
232db589e3
5 changed files with 128 additions and 38 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
32
src/bar.c
32
src/bar.c
|
@ -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);
|
||||||
|
|
10
src/editor.c
10
src/editor.c
|
@ -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
102
src/vip.c
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue