From b5e3328f64c1f47c9df03ec8eb7c1098c5f7df83 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 26 Oct 2026 18:27:07 -0300 Subject: finally finished this. it should be 1:1 with the original rust version... --- src/colors.c | 44 ++++++- src/main.c | 384 +++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 307 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/colors.c b/src/colors.c index 0978c60..973ebf6 100644 --- a/src/colors.c +++ b/src/colors.c @@ -560,17 +560,49 @@ ColorParseError parse_color(const char *s, rgbcolor *out){ const char *color_parse_error_message(ColorParseError error){ switch(error){ case COLOR_ERR_FORMAT: - return "Invaliid color format"; + return "Invalid color format"; case COLOR_ERR_HEX: - return "Invaliid hex color code"; + return "Invalid hex color code"; case COLOR_ERR_RGB: - return "Invaliid RGB format. Expected format: R,G,B"; + return "Invalid RGB format. Expected format: R,G,B"; case COLOR_ERR_HSL: - return "Invaliid HSL format. Expected format: hsl(H,S%,L%)"; - case COLOR_ERR_UNKNOWN_NAME: - return "Unkown named color"; + return "Invalid HSL format. Expected format: hsl(H,S%,L%)"; case COLOR_OK: default: return ""; } +} +static const char *color_mode_name(color_mode mode){ + switch(mode){ + case MODE_TRUECOLOR: return "Truecolor"; + case MODE_ANSI256: return "Ansi256"; + case MODE_ANSI16: return "Ansi16"; + case MODE_NONE: + default: return "NoColor"; + } +} + +static void print_env_debug(const char *name){ + const char *value = getenv(name); + if(value) + printf("%s: Some(\"%s\")\n", name, value); + else + printf("%s: None\n", name); +} + +void print_color_debug(const colorconfig *config, bool ansi_enabled){ + printf("Detected color mode: %s\n", color_mode_name(config->mode)); + printf("ANSI enabled: %s\n", ansi_enabled ? "true" : "false"); + print_env_debug("NO_COLOR"); + print_env_debug("COLORTERM"); + print_env_debug("TERM"); +#ifdef _WIN32 + { + const char *shell = detect_windows_shell(); + if(shell) + printf("Windows shell hint: Some(\"%s\")\n", shell); + else + printf("Windows shell hint: None\n"); + } +#endif } diff --git a/src/main.c b/src/main.c index 350832e..00c6f5f 100644 --- a/src/main.c +++ b/src/main.c @@ -16,28 +16,46 @@ static struct win term = {80, 24}; //if the function fails this is the defualt #ifdef _WIN32 #include - //i have no way to test this because i don't have any windows pc in my house qwq - //(i asked claude to write this for windows because i never looked at the windows api in my life) static void getterminalsize(void) { + CONSOLE_SCREEN_BUFFER_INFO info; + HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); + int found = GetConsoleScreenBufferInfo(console, &info); + SetConsoleOutputCP(CP_UTF8); - CONSOLE_SCREEN_BUFFER_INFO csbi; - if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { - term.winwidth = csbi.srWindow.Right - csbi.srWindow.Left + 1; - term.winheight = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + if(!found){ + HANDLE fallback = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if(fallback != INVALID_HANDLE_VALUE){ + found = GetConsoleScreenBufferInfo(fallback, &info); + CloseHandle(fallback); + } + } + if(found){ + term.winwidth = info.srWindow.Right - info.srWindow.Left + 1; + term.winheight = info.srWindow.Bottom - info.srWindow.Top + 1; } } -#else //or this if they're not on windows which should be posixish like linux or macos +#else #include #include + #include static void getterminalsize(void) { - struct winsize ws; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) { - if(ws.ws_col > 0) - term.winwidth = ws.ws_col; - if(ws.ws_row > 0) - term.winheight = ws.ws_row; + struct winsize size_info; + int tty_descriptor = -1; + int status = ioctl(STDOUT_FILENO, TIOCGWINSZ, &size_info); + + if(status != 0){ + tty_descriptor = open("/dev/tty", O_RDONLY); + if(tty_descriptor >= 0) + status = ioctl(tty_descriptor, TIOCGWINSZ, &size_info); + } + if(status == 0){ + if(size_info.ws_col > 0) term.winwidth = size_info.ws_col; + if(size_info.ws_row > 0) term.winheight = size_info.ws_row; } + if(tty_descriptor >= 0) + close(tty_descriptor); } #endif @@ -154,11 +172,9 @@ char **wraptext(const char *text, int max, int *count){ #define MIN_BUBBLE_WIDTH 20 char **getbubblelines(char *text){ char **templines = wraptext(text, MAX_BUBBLE_WIDTH - 4, &count); - if(templines == NULL) - return NULL; size_t content_width = 0; - for (int i = 0; templines[i] != NULL; i++) { + for (int i = 0; templines != NULL && templines[i] != NULL; i++) { size_t current_len = displaywidth(templines[i]); if (current_len > content_width) content_width = current_len; @@ -185,7 +201,7 @@ char **getbubblelines(char *text){ strcat(bubblelines[0], horizontal); strcat(bubblelines[0], top_right); - for (int i = 0; lines[i] != NULL; i++) { + for (int i = 0; lines != NULL && lines[i] != NULL; i++) { int line_width = displaywidth(lines[i]); int padding_needed = (bubble_width - 2) - line_width; if (padding_needed < 0) padding_needed = 0; @@ -215,15 +231,17 @@ static void print_help(void){ "Arguments:\n" " [TEXT] Text to display in the speech bubble\n\n" "Options:\n" - " -s, --style