tSet editor mode, improve cursor navigation - ve - a minimal text editor (work in progress)
(HTM) git clone git://src.adamsgaard.dk/ve
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 812ddc49f3f4312a59bf50452a2b5384160dd415
(DIR) parent b8e623a52f0e936fd1a85796f6ab7af8d030fac7
(HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
Date: Tue, 6 Aug 2019 11:11:16 +0200
Set editor mode, improve cursor navigation
Diffstat:
M byote.h | 11 +++++++++++
M input.c | 65 +++++++++++++++++++++++++++----
M output.c | 42 +++++++++++++++++++++-----------
M terminal.c | 7 +++++--
M terminal.h | 10 ----------
5 files changed, 102 insertions(+), 33 deletions(-)
---
(DIR) diff --git a/byote.h b/byote.h
t@@ -1,7 +1,18 @@
#ifndef BYOTE_H_
#define BYOTE_H_
+#include <termios.h>
+
#define PROGNAME "byote"
#define VERSION "0.0.1"
+struct editor_config {
+ int cursor_x, cursor_y;
+ int screen_rows, screen_cols;
+ struct termios orig_termios;
+ int status_height;
+ int mode; /* 0: normal, 1: insert, 2: visual */
+};
+
+extern struct editor_config E;
#endif
(DIR) diff --git a/input.c b/input.c
t@@ -1,18 +1,69 @@
#include <unistd.h>
#include <stdlib.h>
+#include "byote.h"
#include "terminal.h"
#define CTRL_KEY(k) ((k) & 0x1f)
void
-editor_process_keypress()
+editor_move_cursor(char key)
{
- char c = editor_read_key();
- switch (c) {
- case CTRL_KEY('q'):
- write(STDOUT_FILENO, "\x1b[2J", 4);
- write(STDOUT_FILENO, "\x1b[H", 3);
- exit(0);
+ switch(key) {
+ case 'h':
+ if (E.cursor_x > 0)
+ E.cursor_x--;
+ break;
+ case 'j':
+ if (E.cursor_y < E.screen_rows - 1 - E.status_height)
+ E.cursor_y++;
+ break;
+ case 'k':
+ if (E.cursor_y > 0)
+ E.cursor_y--;
+ break;
+ case 'l':
+ if (E.cursor_x < E.screen_cols - 1)
+ E.cursor_x++;
break;
}
}
+
+void
+editor_process_keypress()
+{
+ char c;
+ int i;
+
+ c = editor_read_key();
+
+ if (E.mode == 0) { /* normal mode */
+ switch (c) {
+ case CTRL_KEY('q'):
+ write(STDOUT_FILENO, "\x1b[2J", 4);
+ write(STDOUT_FILENO, "\x1b[H", 3);
+ exit(0);
+ break;
+ case 'h':
+ case 'j':
+ case 'k':
+ case 'l':
+ editor_move_cursor(c);
+ break;
+
+ case CTRL_KEY('d'):
+ i = E.screen_rows/2;
+ while (i--)
+ editor_move_cursor('j');
+ break;
+ case CTRL_KEY('u'):
+ i = E.screen_rows/2;
+ while (i--)
+ editor_move_cursor('k');
+ break;
+
+ case '0':
+ E.cursor_x = 0;
+ break;
+ }
+ }
+}
(DIR) diff --git a/output.c b/output.c
t@@ -31,24 +31,35 @@ ab_free(struct abuf *ab) {
void
draw_status(struct abuf *ab)
{
- char left_status[80], right_status[80];
+ E.status_height = 1;
+ char left_status[512], right_status[512];
int left_status_len, right_status_len, padding;
- left_status_len = snprintf(left_status, sizeof(left_status),
- "%s editor -- version %s",
- PROGNAME, VERSION);
+
+ left_status_len = 0;
+ switch (E.mode) {
+ case 1:
+ left_status_len = snprintf(left_status, sizeof(left_status),
+ "INSERT");
+ break;
+ case 2:
+ left_status_len = snprintf(left_status, sizeof(left_status),
+ "VISUAL");
+ break;
+ }
+
right_status_len = snprintf(right_status, sizeof(right_status),
"%s editor -- version %s",
PROGNAME, VERSION);
- if (left_status_len > E.screencols)
- left_status_len = E.screencols;
+ if (left_status_len > E.screen_cols)
+ left_status_len = E.screen_cols;
- padding = E.screencols - left_status_len - right_status_len;
+ padding = E.screen_cols - left_status_len - right_status_len;
if (padding < 0) {
- if (left_status_len < E.screencols)
+ if (left_status_len < E.screen_cols)
ab_append(ab, left_status, left_status_len);
else
- ab_append(ab, left_status, E.screencols);
+ ab_append(ab, left_status, E.screen_cols);
} else {
ab_append(ab, left_status, left_status_len);
while (padding--)
t@@ -63,21 +74,21 @@ void
editor_draw_rows(struct abuf *ab)
{
int y;
- for (y = -1; y < E.screenrows; ++y) {
+ for (y = -1; y < E.screen_rows; ++y) {
- if (y == E.screenrows-1)
+ if (y == E.screen_rows-1)
draw_status(ab);
else
ab_append(ab, "~", 1);
ab_append(ab, "\x1b[K", 3); /* erase to end of line */
- if (y < E.screenrows - 1)
+ if (y < E.screen_rows - 1)
ab_append(ab, "\r\n", 2);
}
}
/* fill output append buffer and write to terminal.
- * move cursor to top left before and after repaint.
+ * move cursor to left before repaint, and to cursor position after.
* hide the cursor when repainting.
* VT100 escape sequences:
* - http://vt100.net/docs/vt100-ug/chapter3.html
t@@ -91,7 +102,10 @@ editor_refresh_screen()
editor_draw_rows(&ab);
- ab_append(&ab, "\x1b[H", 3); /* cursor to home */
+ char buf[32];
+ snprintf(buf, sizeof(buf), "\x1b[%d;%dH", E.cursor_y+1, E.cursor_x+1);
+ ab_append(&ab, buf, strlen(buf));
+
ab_append(&ab, "\x1b[?25h", 6); /* show cursor */
write(STDOUT_FILENO, ab.b, ab.len);
(DIR) diff --git a/terminal.c b/terminal.c
t@@ -5,7 +5,7 @@
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
-#include "terminal.h"
+#include "byote.h"
struct editor_config E;
t@@ -108,6 +108,9 @@ get_window_size(int *rows, int *cols)
void
init_editor() {
- if (get_window_size(&E.screenrows, &E.screencols) == -1)
+ E.cursor_x = 0;
+ E.cursor_y = 0;
+ E.mode = 0;
+ if (get_window_size(&E.screen_rows, &E.screen_cols) == -1)
die("get_window_size");
}
(DIR) diff --git a/terminal.h b/terminal.h
t@@ -1,16 +1,6 @@
#ifndef TERMINAL_H_
#define TERMINAL_H_
-#include <termios.h>
-
-struct editor_config {
- int screenrows;
- int screencols;
- struct termios orig_termios;
-};
-
-extern struct editor_config E;
-
void die(const char *s);
void disable_raw_mode();
void enable_raw_mode();