From d4a4f5ebb2ce74fc18ba51ca8153a37f43e3b80b Mon Sep 17 00:00:00 2001 From: nova Date: Sat, 10 May 2025 21:51:09 +0200 Subject: [PATCH] parsing of /etc/DIR_COLORS --- backend.c | 35 +++++++++++--- colors.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ defines.h | 19 +++++--- window.c | 16 +++++-- 4 files changed, 190 insertions(+), 16 deletions(-) create mode 100644 colors.c diff --git a/backend.c b/backend.c index fd152b4..34e8574 100644 --- a/backend.c +++ b/backend.c @@ -54,30 +54,47 @@ void get_dir_content(char *path, unsigned long *dir_file_count, file *dir_conten if (S_ISDIR(file->st_mode)) { dir_content[i].file_type = COLOR_DIR; + dir_content[i].color_pair = COLOR_DIR; } else if (S_ISBLK(file->st_mode)) { dir_content[i].file_type = COLOR_BLOCK; - } else if (S_ISCHR(file->st_mode)) { - dir_content[i].file_type = COLOR_CHARDEV; + dir_content[i].color_pair = COLOR_BLOCK; + /*} else if (S_ISCHR(file->st_mode)) { + dir_content[i].file_type = COLOR_CHARDEV; */ } else if (S_ISLNK(file->st_mode)) { dir_content[i].file_type = COLOR_SYMLINK; + dir_content[i].color_pair = COLOR_SYMLINK; } else if (S_ISFIFO(file->st_mode)) { dir_content[i].file_type = COLOR_FIFO; + dir_content[i].color_pair = COLOR_FIFO; } else if (S_ISSOCK(file->st_mode)) { dir_content[i].file_type = COLOR_SOCK; + dir_content[i].color_pair = COLOR_SOCK; } else if (S_ISREG(file->st_mode)) { dir_content[i].file_type = COLOR_REGULAR; + dir_content[i].color_pair = COLOR_REGULAR; unsigned long j = 0; char *extension = strrchr(entry[i]->d_name, '.'); if (extension) { for (j = 0; j < color_count; j++) { if (!strcmp(colors[j].file_extension, extension)) { - dir_content[i].file_type = colors[j].color_pair; + dir_content[i].color_pair = colors[j].color_pair; } } } else { } } else { dir_content[i].file_type = COLOR_REGULAR; + dir_content[i].color_pair = COLOR_REGULAR; + unsigned long j = 0; + char *extension = strrchr(entry[i]->d_name, '.'); + if (extension) { + for (j = 0; j < color_count; j++) { + if (!strcmp(colors[j].file_extension, extension)) { + dir_content[i].color_pair = colors[j].color_pair; + } + } + } else { + } } free(file); } @@ -94,9 +111,15 @@ void print_dir(WINDOW *win, unsigned long *dir_file_count, file *dir_content){ unsigned long i = 0; for (i = 0; i < *dir_file_count; i++) { - wattron(win, COLOR_PAIR(dir_content[i].file_type)); - mvwprintw(win, i, 0, "%d", dir_content[i].file_type); + wattron(win, COLOR_PAIR(dir_content[i].color_pair)); + if (dir_content[i].status & FILE_STATUS_HOVER) { + wattron(win, A_REVERSE); + } + mvwprintw(win, i, 0, "%d", dir_content[i].color_pair); mvwaddstr(win, i, 3,dir_content[i].file_name); - wattroff(win, COLOR_PAIR(dir_content[i].file_type)); + if (dir_content[i].status & FILE_STATUS_HOVER) { + wattroff(win, A_REVERSE); + } + wattroff(win, COLOR_PAIR(dir_content[i].color_pair)); } } diff --git a/colors.c b/colors.c new file mode 100644 index 0000000..a824fc0 --- /dev/null +++ b/colors.c @@ -0,0 +1,136 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include "defines.h" + +unsigned int color_count; +color *colors; + +extern file *rgt_content; +extern unsigned long rgt_file_count; + +extern unsigned int settings; + +void parse_colors(char *line, short *fg, short *bg){ + int tmp; + /* cuts everything before the space, then uses ';' as the token delimeter */ + char *token = strtok(strrchr(line, ' '), ";"); + while (token != NULL) { + sscanf(token, "%d", &tmp); + /* magic numbers are ansi color codes */ + if ( tmp > 29 && tmp < 38) { + *fg = tmp - 30; + } else if ( tmp > 39 && tmp < 48) { + *bg = tmp - 40; + } + token = strtok(NULL, ";"); + } +} + + +void colors_init() { + if (has_colors()) { + settings |= SETTINGS_HAS_COLOR; + start_color(); + color_count = 0; + + + init_pair(0, COLOR_WHITE, COLOR_BLACK); /* unknown file */ + + + FILE *dircolors = fopen("/etc/DIR_COLORS", "r"); + if (dircolors) { + char *line; + char *token; + char *extension; + int tmp = 0; + size_t size = 0; + short fg; + short bg; + + char supported_filetype_count = 8; + char initial_pass = 0; + while ((tmp = getline(&line, &size, dircolors)) != -1 && initial_pass != supported_filetype_count) { + fg = 7; + bg = 0; + token = strtok(line, " "); + if (!strcmp(token, "DIR")) { + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(1, fg, bg); /* directory */ + } else if (!strcmp(token, "RESET")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(2, fg, bg); /* regular file */ + } else if (!strcmp(token, "LINK")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(3, fg, bg); /* symlink */ + } else if (!strcmp(token, "SOCK")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(7, fg, bg); /* socket */ + } else if (!strcmp(token, "FIFO")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(6, fg, bg); /* fifo */ + } else if (!strcmp(token, "BLK")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(4, fg, bg); /* block device */ + } else if (!strcmp(token, "CHR")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(5, fg, bg); /* character device */ + } else if (!strcmp(token, "ORPHAN")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(8, fg, bg); /* orphan */ + } else if (!strcmp(token, "EXEC")){ + initial_pass++; + parse_colors(line, &fg, &bg); + init_pair(9, fg, bg); /* exec */ + } + } + + /* checks for only extensions (*.[extension], includes the '.') as the filetypes are handled seperately */ + while ((tmp = getline(&line, &size, dircolors)) != -1) { + if (line[0] == '.') { + color_count++; + } + } + rewind(dircolors); + + colors = malloc(sizeof(color) * color_count); + unsigned int i = 0; + /* proper pass, reads all defined extensions within /etc/DIR_COLORS */ + while ((tmp = getline(&line, &size, dircolors)) != -1) { + fg = 7; + bg = 0; + if (line[0] == '.') { + extension = strtok(line, " "); + colors[i].file_extension = malloc(sizeof(extension)); + strcpy(colors[i].file_extension, extension); + + colors[i].color_pair = i+9; + parse_colors(line, &fg, &bg); + init_pair(i+10, fg, bg); + i++; + + } + } + } else { + init_pair(0, COLOR_WHITE, COLOR_BLACK); /* unknown file */ + init_pair(1, COLOR_BLUE, COLOR_BLACK); /* directory */ + init_pair(2, COLOR_WHITE, COLOR_BLACK); /* regular file */ + init_pair(3, COLOR_YELLOW, COLOR_BLACK); /* symlink */ + init_pair(4, COLOR_CYAN, COLOR_BLACK); /* block device */ + init_pair(5, COLOR_YELLOW, COLOR_BLACK); /* character device */ + init_pair(6, COLOR_MAGENTA, COLOR_BLACK); /* fifo */ + init_pair(7, COLOR_YELLOW, COLOR_BLACK); /* socket */ + init_pair(8, COLOR_BLACK, COLOR_BLUE); /* reserved */ + } + } +} diff --git a/defines.h b/defines.h index 50aa73e..28c2d8b 100644 --- a/defines.h +++ b/defines.h @@ -16,22 +16,29 @@ #define FILE_MODIFIERS_SORT_REVERSE 64 /*FILE_MODIFIERS_SORT_NATURAL is when bitmask is 0*/ -#define COLOR_REGULAR 0 +#define FILE_STATUS_HOVER 1 +#define FILE_STATUS_SELECTED 2; +#define FILE_STATUS_IS_REGULAR_FILE 4 + #define COLOR_DIR 1 -#define COLOR_BLOCK 2 -#define COLOR_CHARDEV 3 +#define COLOR_EXEC 2 +#define COLOR_REGULAR 3 #define COLOR_SYMLINK 4 -#define COLOR_FIFO 5 -#define COLOR_SOCK 6 -#define COLOR_PATH +#define COLOR_BLOCK 5 +#define COLOR_CHARDEV 6 +#define COLOR_FIFO 0 +#define COLOR_SOCK 8 +#define COLOR_PATH 9 #ifndef GUARD #define GUARD /* complex types are good actually */ typedef struct File { + char status; char *file_name; unsigned char file_type; + unsigned short color_pair; unsigned long file_name_width; unsigned long file_size_bytes; } file; diff --git a/window.c b/window.c index 1b79000..4a268bb 100644 --- a/window.c +++ b/window.c @@ -4,6 +4,9 @@ extern unsigned int status; +extern unsigned int color_count; +extern color *colors; + extern file *mid_content; extern file *lft_content; extern file *rgt_content; @@ -82,11 +85,16 @@ void window_rgt(WINDOW *win){ unsigned long local_height; getmaxyx(win, local_height, local_width); if (pthread_mutex_trylock(&mutex_rgt)) { + mvwprintw(win, local_height/2, local_width/2, "LOADING"); + status |= STATUS_UPDATE_SCREEN_0; } else { - /* + int i = 0; + for (i = 0; i < color_count; i++) { + wattron(win, COLOR_PAIR(colors[i].color_pair)); + mvwprintw(win, i, 0, "%d", colors[i].color_pair); + mvwaddstr(win, i, 3,colors[i].file_extension); + wattroff(win, COLOR_PAIR(colors[i].color_pair)); + } pthread_mutex_unlock(&mutex_rgt); - mvwprintw(win, local_height/2, local_width/2, "%ld %ld", rgt_length_width[0], rgt_length_width[1]); - print_dir(win, rgt_length_width, rgt_file_name_width, rgt_content); - */ } }