Thumbnail

rani/cscroll.git

Clone URL: https://git.buni.party/rani/cscroll.git

commit cce43ff18656b13c9b07bc797a790dccfa704639 Author: Raniconduh <clagv.randomgames@gmail.com> Date: Thu Sep 30 21:55:05 2021 +0000 Reorganized code diff --git a/include/dir.h b/include/dir.h new file mode 100644 index 0000000..878913c --- /dev/null +++ b/include/dir.h @@ -00 +134 @@ +#ifndef DIR_H +#define DIR_H +#endif + +int list_dir(char *); +void free_dir_entries(void); +void cd_back(void); +void enter_dir(char *); + + +enum file_type_t { + FILE_REG, + FILE_DIR, + FILE_FIFO, + FILE_LINK, + FILE_BLK, + FILE_UNKNOWN +}; + +struct dir_entry_t { + char * name; + enum file_type_t file_type; +} dir_entry_t; + + +// number of directory entries +extern size_t n_dir_entries; +// actual directory entries +extern struct dir_entry_t ** dir_entries; + +// current working directory +extern char * cwd; + + diff --git a/include/io.h b/include/io.h new file mode 100644 index 0000000..685e75b --- /dev/null +++ b/include/io.h @@ -00 +131 @@ +#ifndef IO_H +#define IO_H +#endif + +#include <stdbool.h> + +enum colors { + BLUE, + HBLUE, + CYAN, + HCYAN, + GREEN, + HGREEN, + MAGENTA, + HMAGENTA, + YELLOW, + HYELLOW, + RED, + HRED, + WHITE, + HWHITE, +}; + +enum keys { + ARROW_UP = 0, + ARROW_DOWN = 1, +}; + +void curses_init(void); +void curses_write_file(struct dir_entry_t *, bool); +char curses_getch(void); diff --git a/src/dir.c b/src/dir.c new file mode 100644 index 0000000..e4c0102 --- /dev/null +++ b/src/dir.c @@ -00 +168 @@ +#include <dirent.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <stdio.h> + +#include "dir.h" + +char * cwd = NULL; + +size_t n_dir_entries = 0; +struct dir_entry_t ** dir_entries = NULL; + +int list_dir(char * dir_path) { + struct dirent * d_entry; + DIR * dir = opendir(dir_path); + + n_dir_entries = 0; + + if (!dir) + return 1; + + while ((d_entry = readdir(dir))) { + struct dir_entry_t * dir_entry = malloc(sizeof(struct dir_entry_t) + 12); + + char * d_name = d_entry->d_name; + size_t d_name_len = strlen(d_name); + + if (!strcmp(d_name, ".") || !strcmp(d_name, "..")) continue; + + struct stat * buf = malloc(sizeof(struct stat)); + char * tmp_path = malloc(d_name_len + strlen(dir_path) + 2); + sprintf(tmp_path, "%s/%s", dir_path, d_name); + stat(tmp_path, buf); + free(tmp_path); + + dir_entries = realloc(dir_entries, sizeof(struct dir_entry_t) * (n_dir_entries + 1)); + dir_entry->name = malloc(d_name_len + 1); + + strcpy(dir_entry->name, d_name); + + mode_t s = buf->st_mode; + if (S_ISBLK(s) || S_ISCHR(s)) dir_entry->file_type = FILE_BLK; + else if (S_ISDIR(s)) dir_entry->file_type = FILE_DIR; + else if (S_ISFIFO(s)) dir_entry->file_type = FILE_FIFO; + else if (S_ISLNK(s)) dir_entry->file_type = FILE_LINK; + else dir_entry->file_type = FILE_REG; + free(buf); + + dir_entries[n_dir_entries] = dir_entry; + + n_dir_entries++; + } + + closedir(dir); + + return 0; +} + + +void free_dir_entries(void) { + for (size_t i = 0; i < n_dir_entries; i++) { + free(dir_entries[i]->name); + free(dir_entries[i]); + } + + n_dir_entries = 0; +} diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000..4ce1fd0 --- /dev/null +++ b/src/io.c @@ -00 +1109 @@ +#include <ncurses.h> +#include <stdbool.h> +#include <string.h> + +#include "dir.h" +#include "io.h" + +void curses_init(void) { + initscr(); + curs_set(0); + start_color(); + + init_pair(BLUE, COLOR_BLUE, COLOR_BLACK); + init_pair(HBLUE, COLOR_BLACK, COLOR_BLUE); + init_pair(CYAN, COLOR_CYAN, COLOR_BLACK); + init_pair(HCYAN, COLOR_BLACK, COLOR_CYAN); + init_pair(GREEN, COLOR_GREEN, COLOR_BLACK); + init_pair(HGREEN, COLOR_BLACK, COLOR_GREEN); + init_pair(MAGENTA, COLOR_MAGENTA, COLOR_BLACK); + init_pair(HMAGENTA, COLOR_BLACK, COLOR_MAGENTA); + init_pair(YELLOW, COLOR_YELLOW, COLOR_BLACK); + init_pair(HYELLOW, COLOR_BLACK, COLOR_YELLOW); + init_pair(RED, COLOR_RED, COLOR_BLACK); + init_pair(HRED, COLOR_BLACK, COLOR_RED); + init_pair(WHITE, COLOR_WHITE, COLOR_BLACK); + init_pair(HWHITE, COLOR_BLACK, COLOR_WHITE); +} + + +void curses_write_file(struct dir_entry_t * dir_entry, bool highlight) { + int cp = -1; + + char f_ident; + if (highlight) { + switch (dir_entry->file_type) { + case FILE_DIR: + cp = HBLUE; + f_ident = '/'; + break; + case FILE_FIFO: + cp = HYELLOW; + f_ident = '|'; + break; + case FILE_BLK: + cp = HYELLOW; + f_ident = '#'; + break; + case FILE_LINK: + cp = HCYAN; + f_ident = '@'; + break; + default: break; + } + if (cp == -1) { + cp = HWHITE; + f_ident = ' '; + } + } else { + switch (dir_entry->file_type) { + case FILE_DIR: + cp = BLUE; + f_ident = '/'; + break; + case FILE_FIFO: + cp = YELLOW; + f_ident = '|'; + break; + case FILE_BLK: + cp = YELLOW; + f_ident = '#'; + break; + case FILE_LINK: + cp = CYAN; + f_ident = '@'; + break; + default: break; + } + if (cp == -1) { + cp = WHITE; + f_ident = ' '; + } + } + + attron(COLOR_PAIR((unsigned)cp)); + printw("%s", dir_entry->name); + attroff(COLOR_PAIR((unsigned)cp)); + printw("%c\n", f_ident); +} + + +char curses_getch(void) { + char c = getch(); + + char seq[5]; + char * ptr = seq; + + if (c == 27) { + *ptr++ = getch(); + *ptr++ = getch(); + *ptr++ = '\0'; + } + + if (!strcmp(seq, "[A")) + return ARROW_UP; + else if (!strcmp(seq, "[B")) + return ARROW_DOWN; + else + return c; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f2da568 --- /dev/null +++ b/src/main.c @@ -00 +151 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <ncurses.h> + +#include "dir.h" +#include "io.h" + +int main(int argc, char ** argv) { + curses_init(); + + if (argc > 1) + cwd = argv[1]; + else + cwd = getenv("PWD"); + + list_dir(cwd); + + size_t cursor = 1; + + while (true) { + erase(); + + printw("\n%s\n\n", cwd); + + for (size_t i = 0; i < n_dir_entries; i++) { + if (cursor - 1 == i) + curses_write_file(dir_entries[i], true); + else + curses_write_file(dir_entries[i], false); + } + + printw("\n%lu/%lu\n", cursor, n_dir_entries); + + refresh(); + + char c = curses_getch(); + if ((c == ARROW_UP || c == 'k') && cursor > 1) + cursor--; + else if ((c == ARROW_DOWN || c == 'j') && cursor < n_dir_entries) + cursor++; + else if (c == 'q') + goto done; + } + +done: + free_dir_entries(); + free(dir_entries); + endwin(); + return 0; +}