From ca5e1323f1ac2a456de4b780ae5e555610b42b37 Mon Sep 17 00:00:00 2001
From: Hadeed Ahmad <hadeedji@gmail.com>
Date: Thu, 31 Aug 2023 09:19:35 +0500
Subject: [PATCH] Move terminal stuff to separate file

---
 .gitignore         |   3 +-
 Makefile           |   3 +-
 include/kilo.h     |  46 ++++++++++++
 include/terminal.h |  17 +++++
 src/kilo.c         | 178 +--------------------------------------------
 src/terminal.c     | 134 ++++++++++++++++++++++++++++++++++
 6 files changed, 204 insertions(+), 177 deletions(-)
 create mode 100644 include/kilo.h
 create mode 100644 include/terminal.h
 create mode 100644 src/terminal.c

diff --git a/.gitignore b/.gitignore
index 6d9567d..2b9f023 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
 build/
 kilo
 
-.ccls-cache
-.nvim.lua
+.cache
 compile_commands.json
diff --git a/Makefile b/Makefile
index 1127dab..25695b3 100644
--- a/Makefile
+++ b/Makefile
@@ -3,8 +3,9 @@ OBJS := $(SRCS:src/%.c=build/%.o)
 DEPS := $(OBJS:%.o=%.d)
 
 WARNING_FLAGS := -Wall -Wextra
-INCLUDE_FLAGS := -I headers
+INCLUDE_FLAGS := -I include
 
+CC := clang
 CFLAGS := $(WARNING_FLAGS) $(INCLUDE_FLAGS) -MMD -MP -std=c99
 
 kilo: $(OBJS)
diff --git a/include/kilo.h b/include/kilo.h
new file mode 100644
index 0000000..8258e02
--- /dev/null
+++ b/include/kilo.h
@@ -0,0 +1,46 @@
+#ifndef KILO_H
+#define KILO_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <termios.h>
+#include <time.h>
+
+struct editor_state {
+    char *filename;
+    int cx, cy;
+    int rx;
+    int screenrows, screencols;
+    int row_off, col_off;
+    bool running;
+
+    struct EROW *rows;
+    int n_rows;
+
+    char message[256];
+    time_t message_time;
+
+    struct termios orig_termios;
+};
+extern struct editor_state E;
+
+typedef uint16_t KEY;
+
+void die(const char *);
+
+enum KEYS {
+    TAB = 9,
+    HOME = 0x100,
+    DEL,
+    PG_UP,
+    PG_DOWN,
+    END,
+    ARROW_UP,
+    ARROW_DOWN,
+    ARROW_LEFT,
+    ARROW_RIGHT,
+    NOP
+};
+
+
+#endif // KILO_H
diff --git a/include/terminal.h b/include/terminal.h
new file mode 100644
index 0000000..b971ce1
--- /dev/null
+++ b/include/terminal.h
@@ -0,0 +1,17 @@
+#ifndef TERMINAL_H
+#define TERMINAL_H
+
+#include <stdbool.h>
+
+#include "kilo.h"
+
+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(void);
+
+#endif // TERMINAL_H
diff --git a/src/kilo.c b/src/kilo.c
index d35a69c..3d96179 100644
--- a/src/kilo.c
+++ b/src/kilo.c
@@ -4,16 +4,14 @@
 #define KILO_TAB_STOP 4
 
 #include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <time.h>
 #include <unistd.h>
 
+#include "kilo.h"
+#include "terminal.h"
+
 #define CTRL_KEY(key) ((key) & 0x1f)
 
 #define MAX(a,b) (((a)>(b))?(a):(b))
@@ -31,38 +29,7 @@ struct EROW {
     int n_rchars;
 };
 
-struct {
-    char *filename;
-    int cx, cy;
-    int rx;
-    int screenrows, screencols;
-    int row_off, col_off;
-    bool running;
-
-    struct EROW *rows;
-    int n_rows;
-
-    char message[256];
-    time_t message_time;
-
-    struct termios orig_termios;
-} E;
-
-enum KEYS {
-    TAB = 9,
-    HOME = 0x100,
-    DEL,
-    PG_UP,
-    PG_DOWN,
-    END,
-    ARROW_UP,
-    ARROW_DOWN,
-    ARROW_LEFT,
-    ARROW_RIGHT,
-    NOP
-};
-
-typedef uint16_t KEY;
+struct editor_state E;
 
 /*****************************************************************************/
 
@@ -88,17 +55,6 @@ int sb_get_size(struct string_buf *);
 void sb_append(struct string_buf *, const char *, int);
 void sb_free(struct string_buf *);
 
-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(void);
-
-void die(const char *);
-
 /*****************************************************************************/
 
 int main(int argc, char **argv) {
@@ -446,132 +402,6 @@ void sb_free(struct string_buf *sb) {
 
 /*****************************************************************************/
 
-int term_enable_raw(void) {
-    if (tcgetattr(STDIN_FILENO, &E.orig_termios) == -1) return -1;
-    atexit(term_disable_raw);
-
-    struct termios raw = E.orig_termios;
-    cfmakeraw(&raw);
-
-    raw.c_cc[VMIN]  = 0;
-    raw.c_cc[VTIME] = 10;
-
-    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) return -1;
-
-    return 0;
-}
-
-void term_disable_raw(void) {
-    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1)
-        die ("term_disable_raw");
-}
-
-int term_clear(void) {
-    if (write(STDOUT_FILENO, "\x1b[2J", 4) != 4) return -1;
-    if (write(STDOUT_FILENO, "\x1b[H", 3) != 3) return -1;
-    return 0;
-
-}
-
-int term_cursor_hidden(bool hidden) {
-    if (write(STDOUT_FILENO, (hidden ? "\x1b[?25l" : "\x1b[?25h"), 6) != 6)
-        return -1;
-
-    return 0;
-}
-
-int term_get_win_size(int *row, int *col) {
-    struct winsize ws;
-
-    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0) {
-        *row = ws.ws_row;
-        *col = ws.ws_col;
-
-        return 0;
-    } else {
-        if (write(STDOUT_FILENO, "\x1b[999C\x1b[999B", 12) != 12) return -1;
-
-        return term_get_cursor_pos(row, col);
-    }
-}
-
-int term_get_cursor_pos(int *row, int *col) {
-    char buf[16];
-
-    if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) return -1;
-
-    for (int i = 0; i < (int) sizeof(buf); i++) {
-        if (read(STDIN_FILENO, buf+i, 1) == 0 || buf[i] == 'R') {
-            buf[i] = '\0';
-            break;
-        }
-    }
-
-    if (sscanf(buf, "\x1b[%d;%d", row, col) == EOF)
-        return -1;
-
-    return 0;
-}
-
-int term_set_cursor_pos(int row, int col) {
-    char buf[16];
-
-    int len = snprintf(buf, sizeof(buf), "\x1b[%d;%dH", row, col);
-    len = (len >= (int) sizeof(buf) ? (int) sizeof(buf) - 1 : len);
-
-    if ((int) write(STDOUT_FILENO, buf, len) != len) return -1;
-    return 0;
-}
-
-KEY term_read_key(void) {
-    char c;
-    while (read(STDIN_FILENO, &c, 1) == 0);
-
-    if (c == '\x1b') {
-        char buf[8] = { '\0' };
-
-        for (int i = 0; i < (int) sizeof(buf); i++) {
-            if (read(STDIN_FILENO, buf+i, 1) == 0) break;
-
-            char escape_char;
-            if (sscanf(buf, "[%c~", &escape_char) != EOF) {
-                switch (escape_char) {
-                    case 'A': return ARROW_UP;
-                    case 'B': return ARROW_DOWN;
-                    case 'C': return ARROW_RIGHT;
-                    case 'D': return ARROW_LEFT;
-                    case 'H': return HOME;
-                    case 'F': return END;
-                }
-            }
-
-            int escape_int;
-            if (sscanf(buf, "[%d~", &escape_int) != EOF) {
-                switch (escape_int) {
-                    case 1:
-                    case 7:
-                        return HOME;
-                    case 3:
-                        return DEL;
-                    case 4:
-                    case 8:
-                        return END;
-                    case 5:
-                        return PG_UP;
-                    case 6:
-                        return PG_DOWN;
-                }
-            }
-        }
-
-        return NOP;
-    }
-
-    return (KEY) c;
-}
-
-/*****************************************************************************/
-
 void die(const char *s) {
     term_clear();
 
diff --git a/src/terminal.c b/src/terminal.c
new file mode 100644
index 0000000..22a6696
--- /dev/null
+++ b/src/terminal.c
@@ -0,0 +1,134 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "kilo.h"
+#include "terminal.h"
+
+int term_enable_raw(void) {
+    if (tcgetattr(STDIN_FILENO, &E.orig_termios) == -1)
+        return -1;
+
+    struct termios raw = E.orig_termios;
+    raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+    raw.c_oflag &= ~(OPOST);
+    raw.c_cflag |= (CS8);
+    raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+    raw.c_cc[VMIN]  = 0;
+    raw.c_cc[VTIME] = 1;
+
+    atexit(term_disable_raw);
+    return tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+void term_disable_raw(void) {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1)
+        die ("term_disable_raw");
+}
+
+int term_clear(void) {
+    if (write(STDOUT_FILENO, "\x1b[2J", 4) != 4) return -1;
+    if (write(STDOUT_FILENO, "\x1b[H", 3) != 3) return -1;
+    return 0;
+
+}
+
+int term_cursor_hidden(bool hidden) {
+    if (write(STDOUT_FILENO, (hidden ? "\x1b[?25l" : "\x1b[?25h"), 6) != 6)
+        return -1;
+
+    return 0;
+}
+
+int term_get_win_size(int *row, int *col) {
+    struct winsize ws;
+
+    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0) {
+        *row = ws.ws_row;
+        *col = ws.ws_col;
+
+        return 0;
+    } else {
+        if (write(STDOUT_FILENO, "\x1b[999C\x1b[999B", 12) != 12) return -1;
+
+        return term_get_cursor_pos(row, col);
+    }
+}
+
+int term_get_cursor_pos(int *row, int *col) {
+    char buf[16];
+
+    if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) return -1;
+
+    for (int i = 0; i < (int) sizeof(buf); i++) {
+        if (read(STDIN_FILENO, buf+i, 1) == 0 || buf[i] == 'R') {
+            buf[i] = '\0';
+            break;
+        }
+    }
+
+    if (sscanf(buf, "\x1b[%d;%d", row, col) == EOF)
+        return -1;
+
+    return 0;
+}
+
+int term_set_cursor_pos(int row, int col) {
+    char buf[16];
+
+    int len = snprintf(buf, sizeof(buf), "\x1b[%d;%dH", row, col);
+    len = (len >= (int) sizeof(buf) ? (int) sizeof(buf) - 1 : len);
+
+    if ((int) write(STDOUT_FILENO, buf, len) != len) return -1;
+    return 0;
+}
+
+KEY term_read_key(void) {
+    char c;
+    while (read(STDIN_FILENO, &c, 1) == 0);
+
+    if (c == '\x1b') {
+        char buf[8] = { '\0' };
+
+        for (int i = 0; i < (int) sizeof(buf); i++) {
+            if (read(STDIN_FILENO, buf+i, 1) == 0) break;
+
+            char escape_char;
+            if (sscanf(buf, "[%c~", &escape_char) != EOF) {
+                switch (escape_char) {
+                    case 'A': return ARROW_UP;
+                    case 'B': return ARROW_DOWN;
+                    case 'C': return ARROW_RIGHT;
+                    case 'D': return ARROW_LEFT;
+                    case 'H': return HOME;
+                    case 'F': return END;
+                }
+            }
+
+            int escape_int;
+            if (sscanf(buf, "[%d~", &escape_int) != EOF) {
+                switch (escape_int) {
+                    case 1:
+                    case 7:
+                        return HOME;
+                    case 3:
+                        return DEL;
+                    case 4:
+                    case 8:
+                        return END;
+                    case 5:
+                        return PG_UP;
+                    case 6:
+                        return PG_DOWN;
+                }
+            }
+        }
+
+        return NOP;
+    }
+
+    return (KEY) c;
+}
+