From aa38851ec8daccfc7ab28346c7b471ce1b42e157 Mon Sep 17 00:00:00 2001 From: Zev Averbach Date: Wed, 11 Jan 2023 22:29:36 +0100 Subject: [PATCH] working except for overflow at end of doc --- input.txt | 3 ++ log.txt | 0 main.c | 146 ++++++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 log.txt diff --git a/input.txt b/input.txt index 06a0b41..77c0d7b 100644 --- a/input.txt +++ b/input.txt @@ -1 +1,4 @@ Hello, Zed! +Foo, Bar! +Test, test + diff --git a/log.txt b/log.txt new file mode 100644 index 0000000..e69de29 diff --git a/main.c b/main.c index 8dbae78..a787151 100644 --- a/main.c +++ b/main.c @@ -2,46 +2,139 @@ #include #include #include +#include #include #include -#define ZED_CAPACITY 1024 +#define EDITOR_CAPACITY 1024 typedef struct { - char data[ZED_CAPACITY]; - size_t count; + size_t begin; + size_t end; +} Line; + +typedef struct { + char data[EDITOR_CAPACITY]; + size_t data_count; + Line lines[EDITOR_CAPACITY + 10]; + size_t lines_count; + size_t cursor; } Editor; +void editor_recompute_lines(Editor *e) { + size_t begin = 0; + for (size_t i = 0; i < e->data_count; ++i) { + if (e->data[i] == '\n') { + e->lines[e->lines_count].begin = begin; + e->lines[e->lines_count].end = i; + e->lines_count += 1; + begin = i + 1; + } + } + e->lines[e->lines_count].begin = begin; + e->lines[e->lines_count].end = e->data_count; + e->lines_count += 1; +} + +size_t editor_current_line(const Editor *e) { + assert(e->cursor <= e->data_count); + for (size_t i = 0; i < e->lines_count; ++i) { + if ( + e->lines[i].begin <= e->cursor + && + e->cursor <= e->lines[i].end + ) return i; + } + return 0; +} + +void editor_rerender(const Editor *e) { + printf("\033[2J\033[H"); // clear screen and go to 0, 0 + fwrite(e->data, 1, e->data_count, stdout); + size_t line = editor_current_line(e); + // position the cursor + printf( + "\033[%zu;%zuH", // '%zu' is a specifier for a `size_t` + line + 1, + e->cursor - e->lines[line].begin + 1 + ); +} + static Editor editor = {0}; -int main(int argc, char **argv) -{ +int editor_start_interactive(Editor *e) { if (!isatty(0)) { fprintf(stderr, "Please run in the terminal!\n"); return 1; } + struct termios term; // stores the state of the terminal + if (tcgetattr(0, &term)) { + fprintf( + stderr, + "ERROR: could not save the state of the terminal: %s\n", + strerror(errno) + ); + return 1; + } + + term.c_lflag = term.c_lflag & ~ECHO; // equivalent of &= ~ECHO + term.c_lflag = term.c_lflag & ~ICANON; + + if (tcsetattr(0, 0, &term)) { + fprintf( + stderr, + "ERROR: could not update the state of the terminal: %s\n", + strerror(errno) + ); + return 1; + } + + bool quit = false; + bool insert = false; + + while (!quit && !feof(stdin)) { + editor_rerender(e); + if (insert) { + + } else { + int x = fgetc(stdin); + switch (x) { + case 'q': { + quit = true; + } break; + case 'h': { + if (e->cursor > 0) { + e->cursor = e->cursor - 1; + } + } break; + case 'l': { + if (e->cursor < EDITOR_CAPACITY) { + e->cursor += 1; + } + } break; + } + } + } + + printf("\033[2J"); + + term.c_lflag |= ECHO; + tcsetattr(0, 0, &term); + return 0; + +} + +int main(int argc, char **argv) +{ if (argc < 2) { fprintf(stderr, "Usage: zed \n"); fprintf(stderr, "ERROR: no input file was provided\n"); return 1; } - // stores the state of the terminal - struct termios term; - if (tcgetattr(0, &term)) { - fprintf(stderr, "ERROR: could not save the state of the terminal: %s\n", strerror(errno)); - return 1; - } - - term.c_lflag &= ~ECHO; - if (tcsetattr(0, 0, &term)) { - fprintf(stderr, "ERROR: could not update the state of the terminal: %s\n", strerror(errno)); - return 1; - } - const char *file_path = argv[1]; FILE *f = fopen(file_path, "rb"); if (f == NULL) { @@ -54,22 +147,11 @@ int main(int argc, char **argv) return 1; } - editor.count = fread(editor.data, 1, ZED_CAPACITY, f); - printf("\ncontents of %s:\n\n", file_path); - fwrite(editor.data, 1, editor.count, stdout); + editor.data_count = fread(editor.data, 1, EDITOR_CAPACITY, f); fclose(f); - bool quit = false; - while (!quit && !feof(stdin)) { - int x = fgetc(stdin); - if (x == 'q') { - quit = true; - } - } + editor_recompute_lines(&editor); - term.c_lflag |= ECHO; - tcsetattr(0, 0, &term); - - return 0; + return editor_start_interactive(&editor); }