From e6cfa02ae4c869ece096de9836daf3cd0d5a79bf Mon Sep 17 00:00:00 2001
From: Hadeed Ahmad <hadeedji@gmail.com>
Date: Sun, 27 Aug 2023 03:08:09 +0500
Subject: [PATCH] More progress towards nothing

---
 Makefile |   2 +-
 kilo.c   | 124 ++++++++++++++++++++++++++++++++-----------------------
 2 files changed, 73 insertions(+), 53 deletions(-)

diff --git a/Makefile b/Makefile
index d8b498d..2dbf63d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS := -Wall -Wextra -Wpedantic -Werror -std=c99
+CFLAGS := -Wall -Wextra -Wpedantic -Wstrict-prototypes -Werror -std=c99
 
 kilo: kilo.c
 	$(CC) $(CFLAGS) kilo.c -o kilo
diff --git a/kilo.c b/kilo.c
index fd94333..01c786d 100644
--- a/kilo.c
+++ b/kilo.c
@@ -55,19 +55,25 @@ enum KEYS {
     NOP
 };
 
+enum SCROLL_DIR {
+    SCROLL_UP,
+    SCROLL_DOWN
+};
+
 typedef uint16_t KEY;
 
 /*****************************************************************************/
 
-void editor_init();
+void editor_init(void);
 void editor_open(char *);
+void editor_redraw_screen(void);
+void editor_process_key(void);
+void editor_draw_rows(void);
 void editor_append_row(const char *, int);
-void editor_redraw_screen();
-void editor_draw_rows();
-void editor_process_key();
-void editor_free();
+void editor_scroll(enum SCROLL_DIR, int);
+void editor_free(void);
 
-struct render_buf *rb_init();
+struct render_buf *rb_init(void);
 void rb_append(struct render_buf *, const char *, int);
 void rb_write(struct render_buf *);
 void rb_clear(struct render_buf *);
@@ -79,14 +85,14 @@ void ib_write(struct input_buf *, KEY);
 bool ib_empty(struct input_buf *);
 void ib_free(struct input_buf *);
 
-int term_enable_raw();
-void term_disable_raw();
-int term_clear();
+int term_enable_raw(void);
+void term_disable_raw(void);
+int term_clear(void);
 int term_cursor_hidden(bool);
 int term_get_win_size(int *, int *);
 int term_get_cursor_pos(int *, int *);
 int term_set_cursor_pos(int, int);
-KEY term_read_key();
+KEY term_read_key(void);
 
 void die(const char *);
 
@@ -147,19 +153,10 @@ void editor_open(char *filename) {
     fclose(file);
 }
 
-void editor_append_row(const char *s, int len) {
-    E.rows = realloc(E.rows, sizeof(struct EROW) * (E.n_rows + 1));
-
-    E.rows[E.n_rows].s = malloc(len);
-    memcpy(E.rows[E.n_rows].s, s, len);
-
-    E.rows[E.n_rows++].size = len;
-}
-
 void editor_redraw_screen() {
     if (term_cursor_hidden(true) == -1) die("term_cursor_hidden");
 
-    editor_draw_rows(E.rb);
+    editor_draw_rows();
     rb_write(E.rb);
     rb_clear(E.rb);
 
@@ -172,6 +169,45 @@ void editor_redraw_screen() {
         die("term_cursor_hidden");
 }
 
+void editor_process_key() {
+    KEY c = ib_read(E.ib);
+
+    switch (c) {
+        case ARROW_LEFT:
+            E.cx = MAX(E.cx - 1, 0);
+            E.col_off = MIN(E.col_off, E.cx);
+            break;
+        case ARROW_DOWN:
+            E.cy = MIN(E.cy + 1, E.n_rows - 1);
+            E.row_off = MAX(E.row_off, E.cy - (E.screenrows - 1));
+            break;
+        case ARROW_UP:
+            E.cy = MAX(E.cy - 1, 0);
+            E.row_off = MIN(E.row_off, E.cy);
+            break;
+        case ARROW_RIGHT:
+            E.cx = MIN(E.cx + 1, INT_MAX);
+            E.col_off = MAX(E.col_off, E.cx - (E.screencols - 1));
+            break;
+
+        case HOME:
+            E.cx = E.col_off = 0;
+            break;
+        case END:
+            E.cx = E.screencols - 1;
+            break;
+
+        case PG_UP:
+        case PG_DOWN:
+            editor_scroll(c == PG_UP ? SCROLL_UP : SCROLL_DOWN, E.screenrows);
+            break;
+
+        case CTRL_KEY('Q'):
+            E.running = false;
+            break;
+    }
+}
+
 void editor_draw_rows() {
     term_set_cursor_pos(1, 1);
 
@@ -181,9 +217,9 @@ void editor_draw_rows() {
 
         if (in_file) {
             struct EROW curr_row = E.rows[y + E.row_off];
-            int max_len = MIN(curr_row.size, E.screencols);
+            int max_len = MIN(curr_row.size - E.col_off, E.screencols);
 
-            rb_append(E.rb, curr_row.s, max_len);
+            rb_append(E.rb, curr_row.s + E.col_off, MAX(max_len, 0));
         } else if (no_file && y == E.screenrows / 2) {
             char welcome[64];
             int len = snprintf(welcome, sizeof(welcome),
@@ -202,40 +238,24 @@ void editor_draw_rows() {
     }
 }
 
-void editor_process_key() {
-    KEY c = ib_read(E.ib);
+void editor_append_row(const char *s, int len) {
+    E.rows = realloc(E.rows, sizeof(struct EROW) * (E.n_rows + 1));
 
-    switch (c) {
-        case ARROW_LEFT:
-            if (E.cx > 0) E.cx--;
-            break;
-        case ARROW_DOWN:
-            if (E.cy < E.n_rows - 1) E.cy++;
-            if (E.cy > E.row_off + E.screenrows - 1) E.row_off = E.cy - E.screenrows + 1;
-            break;
-        case ARROW_UP:
-            if (E.cy > 0) E.cy--;
-            if (E.row_off > E.cy) E.row_off = E.cy;
-            break;
-        case ARROW_RIGHT:
-            if (E.cx < E.screencols - 1) E.cx++;
-            break;
+    E.rows[E.n_rows].s = malloc(len);
+    memcpy(E.rows[E.n_rows].s, s, len);
 
-        case HOME:
-            E.cx = 0;
-            break;
-        case END:
-            E.cx = E.screencols - 1;
-            break;
+    E.rows[E.n_rows++].size = len;
+}
 
-        case PG_UP:
-        case PG_DOWN:
-            for (int i = 0; i < E.screenrows; i++)
-                ib_write(E.ib, (c == PG_UP ? ARROW_UP : ARROW_DOWN));
+void editor_scroll(enum SCROLL_DIR dir, int num) {
+    switch (dir) {
+        case SCROLL_UP:
+            E.row_off = MAX(E.row_off - num, 0);
+            E.cy = MIN(E.cy, E.screenrows + E.row_off - 1);
             break;
-
-        case CTRL_KEY('Q'):
-            E.running = false;
+        case SCROLL_DOWN:
+            E.row_off = MIN(E.row_off + num, E.n_rows - E.screenrows);
+            E.cy = MAX(E.cy, E.row_off);
             break;
     }
 }