From 2b0996e6d553e382766aafc053c215c72c023a81 Mon Sep 17 00:00:00 2001 From: Tomas Rivera <137088692+Totorile1@users.noreply.github.com> Date: Thu, 9 Apr 2026 18:00:34 +0200 Subject: [PATCH] Fixed crash when resizing the window --- .gitignore | 2 + README.md | 2 + src/main.c | 2 + src/ui.c | 10 +-- src/utils.c | 172 +++++++++++++++++++++++++++++----------------------- 5 files changed, 108 insertions(+), 80 deletions(-) diff --git a/.gitignore b/.gitignore index 0d3ecb3..1cc9ced 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ a.out nvimnotes notewrapper nw +error.log +output.log diff --git a/README.md b/README.md index b63319f..ab3b520 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ Change `~/.config/notewrapper/config.json`. If it does not exist. On building, i - [x] Port vivify.vim to nixpkgs - [ ] Add a way to have vaults in different directories - [ ] some kind of FZF search for notes +- [ ] A button to randomly select a note or an entry in a journal +- [x] Fix crash when the window is resized - [x] Actually open vivify when opening nvim - [x] Write the journaling code (separate files or one big journal files) - [x] Adapt createNewNote with journals diff --git a/src/main.c b/src/main.c index 33ee401..a06a515 100644 --- a/src/main.c +++ b/src/main.c @@ -267,6 +267,8 @@ int main(int argc, char *argv[]) { if (doesBackup) { // (TODO LATER) when implementing multiple directories for vault we should verifiy this works. handleBackups(notesDirectoryString, pathToBackup, homedir, interval, shouldDebug); } + + initscr(); //initialize ncurses int shouldExit = 0; while(!shouldExit) { diff --git a/src/ui.c b/src/ui.c index d333a16..2c9eb8c 100644 --- a/src/ui.c +++ b/src/ui.c @@ -1,5 +1,4 @@ #include "ui.h" -#include void createNewVault(char *dirToVault, int bypass, char *bypassvalue, int shouldDebug) { // (TODO LATER) warn if it matches the regex for the journal @@ -8,7 +7,6 @@ void createNewVault(char *dirToVault, int bypass, char *bypassvalue, int shouldD input_screen: char *vaultName = malloc(PATH_MAX); if (!bypass) { // if won't bypass (if -v or --vault weren't set) - initscr(); echo(); keypad(stdscr, FALSE); // color code from https://stackoverflow.com/a/73396575 @@ -30,6 +28,9 @@ input_screen: wgetnstr(stdscr, vaultName, sizeof(vaultName)-1); refresh(); endwin(); + reset_shell_mode(); + fflush(stdout); + fflush(stderr); } else { strncpy(vaultName, bypassvalue, PATH_MAX -2); // -2 (and later -1) because indexing vaultName[PATH_MAX-1] = '\0'; // (TODO LATER) if bypassvalue << PATH_MAX, we loose a lot of space. maybe check strlen(bypassvalue) and append there a \0 @@ -59,7 +60,6 @@ char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, int bypass, c // input from user for the name char *fileName = malloc(BUFFER_SIZE); if (!bypass) { // if we don't bypass. (if -n or --note weren't set.) - initscr(); echo(); keypad(stdscr, FALSE); clear(); @@ -70,6 +70,9 @@ char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, int bypass, c wgetnstr(stdscr, fileName, BUFFER_SIZE-4); //limits the buffer to prevent overflow (-4 to account indexing and from ".md" in case we need to add it later) refresh(); endwin(); + reset_shell_mode(); + fflush(stdout); + fflush(stderr); } else { // bypasses user input if we bypass is set to 1 strncpy(fileName, bypassvalue, BUFFER_SIZE-1); // (TODO LATER) Maybe add a warning if string is too big. It gets truncated fileName[BUFFER_SIZE-1] = '\0'; @@ -146,7 +149,6 @@ char* ncursesSelect(char **options, char *optionsText, size_t optionsNumber, siz int highlight = 0; //curently highlighted option int key; - initscr(); //initialize ncurses cbreak(); // disable line buffering noecho(); // don't echo key presses keypad(stdscr, TRUE); // enable arrow keys diff --git a/src/utils.c b/src/utils.c index 89292d0..dbda7ff 100644 --- a/src/utils.c +++ b/src/utils.c @@ -9,12 +9,22 @@ int compareString(const void *a, const void *b) { return strcmp(str1, str2); // strcmp returns <0, 0, >0 } +void getCurrentTime(int *hour, int *minute, int *second) { + time_t now = time(NULL); // Get current time in seconds since epoch + struct tm *local = localtime(&now); // Convert to local time structure + + *hour = local->tm_hour; // Extract hour + *minute = local->tm_min; // Extract minutes + *second = local->tm_sec; // Extract seconds +} + void _debug(const int d, const char *file, const int line, const char *function, const char *message, ...) { // use for formatted debug if (d) { va_list args; //variadic function stuff va_start(args, message); - - fprintf(stderr, "\e[0;32m[DEBUG] From file %s line %d function %s:\e[0m\n", file, line, function); + int h, m, s; + getCurrentTime(&h, &m, &s); + fprintf(stderr, "\e[0;32m[DEBUG -- %d:%d:%d] From file %s line %d function %s:\e[0m\n", h, m, s, file, line, function); vfprintf(stderr, message, args); printf("\e[0m\n"); va_end(args); @@ -31,7 +41,9 @@ void _altDebug(const int d, const char *message, ...) { // use for less formal d void _error(const int shouldDebug, const int condition, const char *type, const char *file, const int line, const char *function, const char *message, ...) { // used for formatted errors if (condition) { - fprintf(stderr, "\e[0;31m[%s ERROR] From file %s line %d function %s:\n", type, file, line, function); + int h, m, s; + getCurrentTime(&h, &m, &s); + fprintf(stderr, "\e[0;31m[%s ERROR -- %d:%d:%d] From file %s line %d function %s:\n", type, h, m, s, file, line, function); if (errno != 0) { fprintf(stderr, " (System-level error message: %s)\n", strerror(errno)); } else { @@ -245,88 +257,96 @@ int rmrf(char *path) { int openEditor(char *path, char *editor, int render, int shouldJumpToEndOfFile, int shouldDebug) { - pid_t editor_pid = fork(); - error(editor_pid < 0, "program", "fork() failed."); +// this ensures that ncurses won't affect the editor behaviour +pid_t editor_pid = fork(); +error(editor_pid < 0, "program", "fork() failed."); - if (editor_pid == 0) { - // ========================= - // CHILD: launch editor - // ========================= +if (editor_pid == 0) { + // ========================= + // CHILD: launch editor + // ========================= - // ---- NEOVIM / VIM ---- - if (strcmp(editor, "neovim") == 0 || strcmp(editor, "vim") == 0) { - const char *bin = (strcmp(editor, "neovim") == 0) ? "nvim" : "vim"; + // ---- NEOVIM / VIM ---- + if (strcmp(editor, "neovim") == 0 || strcmp(editor, "vim") == 0) { + const char *bin = (strcmp(editor, "neovim") == 0) ? "nvim" : "vim"; - if (render) { - if (shouldJumpToEndOfFile) { - debug("Running %s +:$ +:Vivify %s", bin, path); - execlp(bin, bin, "+:$", "+:Vivify", path, NULL); - } else { - debug("Running %s +:Vivify %s", bin, path); - execlp(bin, bin, "+:Vivify", path, NULL); - } - } else { - if (shouldJumpToEndOfFile) { - debug("Running %s +:$ %s", bin, path); - execlp(bin, bin, "+:$", path, NULL); - } else { - debug("Running %s %s", bin, path); - execlp(bin, bin, path, NULL); - } - } - - error(1, "program", "execlp() failed."); - } - - // ---- NANO ---- - else if (strcmp(editor, "nano") == 0) { - - // If render enabled → spawn viv in parallel - if (render) { - pid_t viv_pid = fork(); - error(viv_pid < 0, "program", "fork() failed."); - - if (viv_pid == 0) { - // GRANDCHILD → viv - char viv_path[PATH_MAX]; - strncpy(viv_path, path, PATH_MAX - 1); - viv_path[PATH_MAX - 1] = '\0'; - - if (shouldJumpToEndOfFile) { - strncat(viv_path, ":99999", - PATH_MAX - strlen(viv_path) - 1); - } - - debug("Running viv %s", viv_path); - execlp("viv", "viv", viv_path, NULL); - error(1, "program", "execlp() failed."); - } - // IMPORTANT: do NOT wait for viv - } - - // Now run nano (this replaces the child process) + if (render) { if (shouldJumpToEndOfFile) { - debug("Running nano + %s", path); - execlp("nano", "nano", "+", path, NULL); + debug("Running %s +:$ +:Vivify %s", bin, path); + execlp(bin, bin, "+:$", "+:Vivify", path, NULL); } else { - debug("Running nano %s", path); - execlp("nano", "nano", path, NULL); + debug("Running %s +:Vivify %s", bin, path); + execlp(bin, bin, "+:Vivify", path, NULL); + } + } else { + if (shouldJumpToEndOfFile) { + debug("Running %s +:$ %s", bin, path); + execlp(bin, bin, "+:$", path, NULL); + } else { + debug("Running %s %s", bin, path); + execlp(bin, bin, path, NULL); } - - error(1, "program", "execlp() failed."); } - // ---- UNKNOWN EDITOR ---- - else { - error(1, "program", "Unknown editor."); - } + error(1, "program", "execlp() failed."); } - // ========================= - // PARENT: wait ONLY editor - // ========================= - int status; - waitpid(editor_pid, &status, 0); + // ---- NANO ---- + else if (strcmp(editor, "nano") == 0) { - return 0; + // If render enabled → spawn viv in parallel + if (render) { + debug("Running the editor..."); + pid_t viv_pid = fork(); + error(viv_pid < 0, "program", "fork() failed."); + + if (viv_pid == 0) { + // GRANDCHILD → viv + + + char viv_path[PATH_MAX]; + strncpy(viv_path, path, PATH_MAX - 1); + viv_path[PATH_MAX - 1] = '\0'; + + if (shouldJumpToEndOfFile) { + strncat(viv_path, ":99999", + PATH_MAX - strlen(viv_path) - 1); + } + + debug("Running viv %s", viv_path); + execlp("viv", "viv", viv_path, NULL); + error(1, "program", "execlp() failed."); + } + // IMPORTANT: do NOT wait for viv + } + + // Now run nano (this replaces the child process) + if (shouldJumpToEndOfFile) { + debug("Running nano + %s", path); + execlp("nano", "nano", "+", path, NULL); + } else { + debug("Running nano %s", path); + execlp("nano", "nano", path, NULL); + } + + error(1, "program", "execlp() failed."); + } + + // ---- UNKNOWN EDITOR ---- + else { + error(1, "program", "Unknown editor."); + } + } + + // ========================= + // PARENT: wait ONLY editor + // ========================= + int status; + while (waitpid(editor_pid, &status, 0) == -1) { // we can't just use waitpid(). Because when resizing the terminal, waitpid() is returned so we loop to see if there is not a problem + if (errno != EINTR) { + perror("waitpid"); + break; + } + } + return 0; }