diff --git a/CMakeLists.txt b/CMakeLists.txt index 01deae3..b7a0a3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ project(editor) set(CMAKE_CXX_STANDARD 17) -add_executable(editor kilo.cpp) +add_executable(editor kilo.c) diff --git a/kilo.c b/kilo.c new file mode 100644 index 0000000..bac1d09 --- /dev/null +++ b/kilo.c @@ -0,0 +1,171 @@ +/*** Includes ***/ +#include +#include +#include +#include +#include +#include +#include +#include + +/** defines ***/ +#define KILO_VERSION "0.0.1" +#define CTRL_KEY(k) ((k) & 0x1f) + + +/*** data ***/ +struct editorConfig { + int screenrows; + int screencols; + struct termios orig_termios; +}; +struct editorConfig E; + +/*** terminal ***/ +void die(const char *s){ + write(STDOUT_FILENO, "\x1b[2J", 4); + write(STDOUT_FILENO, "\x1b[H", 3); + + perror(s); + exit(1); +} + +void disableRawMode() { + if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1){ + die("tcsetattr"); + } +} + +void enableRawMode() { + if(tcgetattr(STDIN_FILENO, &E.orig_termios) == -1) die("tcgetattr"); + + atexit(disableRawMode); + + 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; + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr"); +} + +char editorReadKey() { + int nread; + char c; + while ((nread = read(STDIN_FILENO, &c, 1)) != 1){ + if (nread == -1 && errno != EAGAIN) die("read"); + } + return c; +} + +int getCursorPosition(int *rows, int *cols) { + char buf[32]; + unsigned int i = 0; + if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) return -1; + + while(i < sizeof(buf) -1) { + if (read(STDIN_FILENO, &buf[i], 1) != 1) break; + if (buf[i] == 'R') break; + i++; + } + buf[i] = '\0'; //assign null to final byte + if(buf[0] != '\x1b' || buf[1] != '[') return -1; + if(sscanf(&buf[2], "%d;%d", rows, cols) != 2) return -1; + return 0; +} + +int getWindowSize(int *rows, int *cols) { + struct winsize ws; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { + if (write(STDOUT_FILENO, "\x1b[999C\x1b[999B",12) != 12) return -1; + return getCursorPosition(rows, cols); + } else { + *cols = ws.ws_col; + *rows = ws.ws_row; + return 0; + } +} +/*** append buffer ***/ +struct abuf { + char *b; + int len; +}; +#define ABUF_INIT {NULL, 0} +void abAppend(struct abuf *ab, const char *s, int len) { + char *new = realloc(ab->b, ab->len + len); + + if (new == NULL) return; + memcpy(&new[ab->len], s, len); + ab->b = new; + ab->len += len; +} +void abFree(struct abuf *ab) { + free(ab->b); +} + + +/*** output ***/ +void editorDrawRows(struct abuf *ab) { + int y; + for (y = 0; y < E.screenrows; y++){ + if (y == E.screenrows / 3) { + char welcome[80]; + int welcomelen = snprintf(welcome, sizeof welcome, "Kilo Editor -- version %s", KILO_VERSION); + int padding = (E.screencols - welcomelen) /2; + if(padding) { + abAppend(ab, "~", 1); + padding--; + } + while(padding--) abAppend(ab, " ", 1); + if (welcomelen > E.screencols) welcomelen = E.screencols; + abAppend(ab, welcome, welcomelen); + } else { + abAppend(ab, "~", 1); + } + abAppend(ab, "\x1b[K", 3); + if (y -#include -#include -#include -#include -#include - -/** defines ***/ -#define CTRL_KEY(k) ((k) & 0x1f) - - -/*** data ***/ -struct termios orig_termios; - -/*** terminal ***/ -void die(const char *s){ - perror(s); - exit(1); -} - -void disableRawMode() { - if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1){ - die("tcsetattr"); - } -} - -void enableRawMode() { - if(tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr"); - - atexit(disableRawMode); - - struct termios raw = 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; - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr"); -} - -char editorReadKey() { - int nread; - char c; - while ((nread = read(STDIN_FILENO, &c, 1)) != 1){ - if (nread == -1 && errno != EAGAIN) die("read"); - } - return c; -} - -/*** output ***/ -void editorRefreshScreen() { - write(STDOUT_FILENO, "\x1b[2J", 4); // Clear Screen - write(STDOUT_FILENO, "\x1b[H",3); // Cursor Position home -} - - -/*** input ***/ -void editorProcessKeypress() { - char c = editorReadKey(); - switch (c) { - case CTRL_KEY('q'): - exit(0); - break; - } -} - -/*** init ***/ -int main() { - enableRawMode(); - - while(1) { - editorRefreshScreen(); - editorProcessKeypress(); - } - return 0; -} \ No newline at end of file