nasmfm

sfm rewrite
git clone https://git.afify.dev/nasmfm.git
Log | Files | Refs | LICENSE

commit bb1400f138800794a5f2dc0e953e09098eecf2bc
parent 69eb6e669536bb7360bab5f1f99eddcfd4903438
Author: afify <hassan@afify.dev>
Date:   Wed,  9 Mar 2022 16:04:17 +0300

[feat] macros cursor

Diffstat:
Mnasmfm.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 95 insertions(+), 16 deletions(-)

diff --git a/nasmfm.c b/nasmfm.c @@ -1,5 +1,7 @@ /* See LICENSE file for copyright and license details. */ +#include <sys/ioctl.h> + #include <ctype.h> #include <errno.h> #include <stdio.h> @@ -8,32 +10,46 @@ #include <unistd.h> /* macros */ +#define CTRL_KEY(k) ((k)&0x1f) +#define CLEAR_SCREEN write(STDOUT_FILENO, "\x1b[2J", 4); +#define CURSOR_TOP_LEFT write(STDOUT_FILENO, "\x1b[H", 3); + /* typedef */ /* function declarations */ /* global variables */ /* function implementations */ -struct termios orig_termios; +typedef struct { + int rows; + int cols; + struct termios orig_termios; +} Term; + +Term term; + void die(const char *s) { + CLEAR_SCREEN + CURSOR_TOP_LEFT perror(s); exit(1); } + void disableRawMode() { - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term.orig_termios) == -1) die("tcsetattr"); } void enableRawMode() { - if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) + if (tcgetattr(STDIN_FILENO, &term.orig_termios) == -1) die("tcgetattr"); atexit(disableRawMode); - struct termios raw = orig_termios; + struct termios raw = term.orig_termios; raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); raw.c_oflag &= ~(OPOST); @@ -45,24 +61,87 @@ enableRawMode() if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr"); } +void +editorDrawRows() +{ + int y; + for (y = 0; y < term.rows; y++) { + write(STDOUT_FILENO, "~", 1); + if (y < term.rows - 1) { + write(STDOUT_FILENO, "\r\n", 2); + } + } +} + +void +editorRefreshScreen() +{ + CLEAR_SCREEN + CURSOR_TOP_LEFT + editorDrawRows(); + CURSOR_TOP_LEFT +} + +char +editorReadKey() +{ + int nread; + char c; + while ((nread = read(STDIN_FILENO, &c, 1)) != 1) { + if (nread == -1 && errno != EAGAIN) + die("read"); + } + return c; +} +/*** input ***/ +void +editorProcessKeypress() +{ + char c = editorReadKey(); + switch (c) { + case CTRL_KEY('q'): + CLEAR_SCREEN + CURSOR_TOP_LEFT + exit(0); + break; + case 'q': + CLEAR_SCREEN + CURSOR_TOP_LEFT + exit(0); + break; + default: + printf("%d ('%c')\r\n", c, c); + } +} + +int +getWindowSize(int *rows, int *cols) +{ + struct winsize ws; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { + return -1; + } else { + *cols = ws.ws_col; + *rows = ws.ws_row; + return 0; + } +} + +void +initEditor() +{ + if (getWindowSize(&term.rows, &term.cols) == -1) + die("getWindowSize"); +} int main(int argc, char *argv[]) { enableRawMode(); + initEditor(); while (1) { - char c = '\0'; - if (read(STDIN_FILENO, &c, 1) == -1 && errno != EAGAIN) - die("read"); - read(STDIN_FILENO, &c, 1); - if (iscntrl(c)) { - printf("%d\r\n", c); - } else { - printf("%d ('%c')\r\n", c, c); - } - if (c == 'q') - break; + editorRefreshScreen(); + editorProcessKeypress(); } - return 0; }