summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Richard <johnny@johnnyrichard.com>2022-04-27 03:40:28 +0200
committerJohnny Richard <johnny@johnnyrichard.com>2022-04-27 03:40:28 +0200
commitc326fe279ddf2fd606578e980f5ed5c8aba614cd (patch)
treee447a25f537077e1cf26d4cc481fe6af88489422
parent9323ebbbe565540bd8406c7870d7d8d92e17397e (diff)
editor: Add multiple rows and scroll support
-rw-r--r--ted.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/ted.c b/ted.c
index 86616b7..e0e842f 100644
--- a/ted.c
+++ b/ted.c
@@ -55,10 +55,11 @@ typedef struct erow {
typedef struct editor {
int cx, cy;
+ int rowoff;
int screen_rows;
int screen_cols;
int num_rows;
- erow_t row;
+ erow_t *row;
struct termios orig_termios;
} editor_t;
@@ -70,6 +71,8 @@ int get_window_size(int *rows, int *cols);
void editor_init(editor_t *e);
void editor_open(editor_t *e, char *filename);
int editor_read_key();
+void editor_append_row(editor_t *e, char *s, size_t len);
+void editor_scroll(editor_t *e);
void editor_move_cursor(editor_t *e, int key);
void editor_process_key(editor_t *e);
void editor_draw_rows(editor_t *e, string_builder_t *sb);
@@ -102,7 +105,9 @@ editor_init(editor_t *e)
{
e->cx = 0;
e->cy = 0;
+ e->rowoff = 0;
e->num_rows = 0;
+ e->row = NULL;
if (get_window_size(&e->screen_rows, &e->screen_cols) == -1) {
die("get_window_size");
}
@@ -116,21 +121,41 @@ editor_open(editor_t *e, char *filename)
char* line = NULL;
size_t lineap = 0;
- ssize_t linelen = getline(&line, &lineap, fp);
- if (linelen != -1) {
+ ssize_t linelen;
+ while((linelen = getline(&line, &lineap, fp)) != -1) {
while (linelen > 0 && (line[linelen - 1] == '\n' || line[linelen - 1] == '\r')) {
linelen--;
}
- e->row.size = linelen;
- e->row.chars = malloc(linelen + 1);
- memcpy(e->row.chars, line, linelen);
- e->row.chars[linelen] = '\0';
- e->num_rows = 1;
+ editor_append_row(e, line, linelen);
}
free(line);
fclose(fp);
}
+void
+editor_append_row(editor_t *e, char *s, size_t len)
+{
+ e->row = realloc(e->row, sizeof(erow_t) * (e->num_rows + 1));
+
+ int at = e->num_rows;
+ e->row[at].size = len;
+ e->row[at].chars = malloc(len + 1);
+ memcpy(e->row[at].chars, s, len);
+ e->row[at].chars[len] = '\0';
+ e->num_rows++;
+}
+
+void
+editor_scroll(editor_t *e)
+{
+ if (e->cy < e->rowoff) {
+ e->rowoff = e->cy;
+ }
+ if (e->cy >= e->rowoff + e->screen_rows) {
+ e->rowoff = e->cy - e->screen_rows + 1;
+ }
+}
+
int
editor_read_key()
{
@@ -251,7 +276,7 @@ editor_move_cursor(editor_t *e, int key)
}
break;
case ARROW_DOWN:
- if (e->cy != e->screen_rows - 1) {
+ if (e->cy < e->screen_rows) {
e->cy++;
}
break;
@@ -303,7 +328,8 @@ void
editor_draw_rows(editor_t *e, string_builder_t *sb)
{
for (int y = 0; y < e->screen_rows; ++y) {
- if (y >= e->num_rows) {
+ int filerow = y + e->rowoff;
+ if (filerow >= e->num_rows) {
if (e->num_rows == 0 && y == e->screen_rows / 3) {
char welcome[80];
int welcomelen = snprintf(welcome, sizeof(welcome), "Ted editor --- version %s", TED_VERSION);
@@ -326,9 +352,9 @@ editor_draw_rows(editor_t *e, string_builder_t *sb)
string_builder_append(sb, "~", 1);
}
} else {
- int len = e->row.size;
+ int len = e->row[filerow].size;
if (len > e->screen_cols) len = e->screen_cols;
- string_builder_append(sb, e->row.chars, len);
+ string_builder_append(sb, e->row[filerow].chars, len);
}
string_builder_append(sb, "\x1b[K", 3);
@@ -341,6 +367,7 @@ editor_draw_rows(editor_t *e, string_builder_t *sb)
void
editor_refresh_screen(editor_t *e)
{
+ editor_scroll(e);
string_builder_t sb = STRING_BUILDER_INIT;
string_builder_append(&sb, "\x1b[?25l", 6);
@@ -349,7 +376,7 @@ editor_refresh_screen(editor_t *e)
editor_draw_rows(e, &sb);
char buf[32];
- snprintf(buf, sizeof(buf), "\x1b[%d;%dH", e->cy + 1, e->cx + 1);
+ snprintf(buf, sizeof(buf), "\x1b[%d;%dH", (e->cy - e->rowoff) + 1, e->cx + 1);
string_builder_append(&sb, buf, strlen(buf));
string_builder_append(&sb, "\x1b[?25h", 6);