commit bb1400f138800794a5f2dc0e953e09098eecf2bc
parent 69eb6e669536bb7360bab5f1f99eddcfd4903438
Author: afify <hassan@afify.dev>
Date: Wed, 9 Mar 2022 16:04:17 +0300
[feat] macros cursor
Diffstat:
M | nasmfm.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;
}