From f86bd0b321d87ef2bda9be37f962d6d70570af6c Mon Sep 17 00:00:00 2001 From: Arthur Barraux Date: Sat, 21 Sep 2024 16:30:15 +0200 Subject: [PATCH] displays rowq and getting terminal size --- Makefile | 2 ++ main.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++---- main.h | 2 ++ 3 files changed, 105 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index d931cd2..0b885d8 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ build: main.c main.h if [ ! -d beluga-output ]; then mkdir beluga-output; fi if [ ! -d beluga-output/build ]; then mkdir beluga-output/build; fi $(CC) main.c -o $(BELUGA_OUTPUT)/$(BUILD_DIR)/beluga $(BUILD_FLAGS) + doxygen DEBUG_DIR=debug @@ -26,5 +27,6 @@ debug: main.c main.h clean: rm -rf $(BELUGA_OUTPUT) + rm -rf doc/ # end diff --git a/main.c b/main.c index 5828b87..780cd2e 100644 --- a/main.c +++ b/main.c @@ -6,17 +6,31 @@ */ #include "main.h" +#include +#include #include #include #include +#include #include #include /* defines */ #define CTRL_KEY(k) ((k) & 0x1f) +#define CURSOR_TOP_LEFT "\x1b[H" /* data */ -struct termios orig_termios; +/** + * \struct editorConfig + * \brief Containing our editor state. + */ +struct editorConfig { + int screenrows; + int screencols; + struct termios orig_termios; +}; + +struct editorConfig E; /* terminal */ @@ -32,18 +46,18 @@ void die(const char *s) { } void disableRawMode() { - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) { + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1) { die("tcsetattr"); } } void enableRawMode() { - if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) { + if (tcgetattr(STDIN_FILENO, &E.orig_termios) == -1) { die("tcgetattr"); } atexit(disableRawMode); - struct termios raw = orig_termios; + struct termios raw = E.orig_termios; raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); raw.c_oflag &= ~(OPOST); raw.c_cflag |= (CS8); @@ -67,16 +81,86 @@ char editorReadKey() { 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'; + + 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; + } +} + /* output */ +/** \fn void wipeScreen() + * \brief Wipe the terminal screen and put the cursor on the top left corner. + * */ void wipeScreen() { /* Clear the screen */ write(STDOUT_FILENO, "\x1b[2J", 4); /* Put the cursor at the top left corner */ - write(STDOUT_FILENO, "\x1b[H", 3); + write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3); +} + +/** + * \fn void editorDrawRows() + * \brief Draws left rows of the editor. + */ +void editorDrawRows() { + int y; + for (y = 0; y < E.screenrows; ++y) { + write(STDOUT_FILENO, "~\r\n", 3); + } +} + +void editorRefreshScreen() { + wipeScreen(); + editorDrawRows(); + + write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3); } /* input */ + +/** + * \fn void editorProcessKeypress() + * \brief Get the last key input and do the proper action. + */ void editorProcessKeypress() { char c = editorReadKey(); @@ -90,12 +174,23 @@ void editorProcessKeypress() { /* init */ +/** + * \fn void initEditor() + * \brief Job's function is to initialize all the fields of editorConfig. + * */ +void initEditor() { + if (getWindowSize(&E.screenrows, &E.screencols) == -1) { + die("getWindowSize"); + } +} + int main() { enableRawMode(); + initEditor(); while (1) { - wipeScreen(); + editorRefreshScreen(); editorProcessKeypress(); } return 0; diff --git a/main.h b/main.h index b8fcafe..6a09166 100644 --- a/main.h +++ b/main.h @@ -9,6 +9,8 @@ char editorReadKey(); /* output */ void wipeScreen(); +void editorDrawRows(); +void editorRefreshScreen(); /* input */ void editorProcessKeypress();