cex

C/Curses file EXplorer
git clone git://git.wimdupont.com/cex.git
Log | Files | Refs | README | LICENSE

commit eac52812742e4760e9682a73dd430af68b9db75b
parent 6d041ddbab6507b22127e4342acd93d9b6c9e2eb
Author: Wim Dupont <wim@wimdupont.com>
Date:   Sat, 13 Jul 2024 19:08:53 +0200

ln fix and colour defs

Diffstat:
Mcex.c | 120++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mcex.h | 15++++++++++++++-
2 files changed, 90 insertions(+), 45 deletions(-)

diff --git a/cex.c b/cex.c @@ -106,11 +106,11 @@ init_screen() init_pair(COLOR_BLACK, COLOR_BLACK, -1); init_pair(COLOR_RED, COLOR_RED, -1); init_pair(COLOR_GREEN,COLOR_GREEN, -1); - init_pair(COLOR_YELLOW, COLOR_YELLOW,-1); - init_pair(COLOR_BLUE, COLOR_BLUE,-1); - init_pair(COLOR_MAGENTA,COLOR_MAGENTA, -1); - init_pair(COLOR_CYAN, COLOR_CYAN,-1); - init_pair(COLOR_WHITE,COLOR_WHITE, -1); + init_pair(COLOR_YELLOW, COLOR_YELLOW, -1); + init_pair(COLOR_BLUE, COLOR_BLUE, -1); + init_pair(COLOR_MAGENTA, COLOR_MAGENTA, -1); + init_pair(COLOR_CYAN, COLOR_CYAN, -1); + init_pair(COLOR_WHITE, COLOR_WHITE, -1); curwin.highlight = 0; curwin.startpr = 0; @@ -440,6 +440,8 @@ print_win(DirWin *dirwin) char name[size+1], sbuf[size+1]; char *subs; int sindex; + char abspath[PATH_MAX]; + char pathbuf[PATH_MAX]; wclear(dirwin->window); @@ -451,9 +453,9 @@ print_win(DirWin *dirwin) mvwaddstr(dirwin->window, y, x, dirwin->message); wattroff(dirwin->window, A_REVERSE); } else { - wattron(dirwin->window, COLOR_PAIR(COLOR_MAGENTA)); + wattron(dirwin->window, COLOR_PAIR(CHILDWIN_MESSAGE_COLOR)); mvwaddstr(dirwin->window, y, x, dirwin->message); - wattroff(dirwin->window, COLOR_PAIR(COLOR_MAGENTA)); + wattroff(dirwin->window, COLOR_PAIR(CHILDWIN_MESSAGE_COLOR)); } } else if (dirwin->winfiles != NULL) { while (!dirwin->usehighlight) { @@ -471,9 +473,9 @@ print_win(DirWin *dirwin) } for (size_t i = dirwin->startpr; i < dirwin->filecount; ++i) { if (dirwin->winfiles[i].selected) { - wattron(dirwin->window, COLOR_PAIR(COLOR_GREEN)); + wattron(dirwin->window, COLOR_PAIR(MARK_SELECTED_COLOR)); mvwaddch(dirwin->window, y, x-1, '|'); - wattroff(dirwin->window, COLOR_PAIR(COLOR_GREEN)); + wattroff(dirwin->window, COLOR_PAIR(MARK_SELECTED_COLOR)); } memcpy(name, dirwin->winfiles[i].d_name, size); name[size-1] = '\0'; @@ -482,27 +484,33 @@ print_win(DirWin *dirwin) mvwaddstr(dirwin->window, y, x, name); wattroff(dirwin->window, A_REVERSE); } else if (dirwin->winfiles[i].d_type == DT_DIR) { - wattron(dirwin->window, COLOR_PAIR(COLOR_BLUE)); + wattron(dirwin->window, COLOR_PAIR(DIR_COLOR)); wattron(dirwin->window, A_BOLD); mvwaddstr(dirwin->window, y, x, name); - wattroff(dirwin->window, COLOR_PAIR(COLOR_BLUE)); + wattroff(dirwin->window, COLOR_PAIR(DIR_COLOR)); wattroff(dirwin->window, A_BOLD); } else if (dirwin->winfiles[i].d_type == DT_LNK) { - wattron(dirwin->window, COLOR_PAIR(COLOR_CYAN)); - mvwaddstr(dirwin->window, y, x, name); - wattroff(dirwin->window, COLOR_PAIR(COLOR_CYAN)); + if (access(get_fullpath(pathbuf, dirwin, i), F_OK) == 0) { + wattron(dirwin->window, COLOR_PAIR(LN_COLOR)); + mvwaddstr(dirwin->window, y, x, name); + wattroff(dirwin->window, COLOR_PAIR(LN_COLOR)); + } else { + wattron(dirwin->window, COLOR_PAIR(INVALID_LN_COLOR)); + mvwaddstr(dirwin->window, y, x, name); + wattroff(dirwin->window, COLOR_PAIR(INVALID_LN_COLOR)); + } } else mvwaddstr(dirwin->window, y, x, name); if (dirwin->wintype == CURRENT && searchc > 0 && ((subs = strstr(name, searchq)) != NULL)) { sindex = (int) (subs - name); - wattron(dirwin->window, COLOR_PAIR(COLOR_RED)); + wattron(dirwin->window, COLOR_PAIR(SEARCH_MATCH_COLOR)); if (dirwin->usehighlight && dirwin->highlight == i) wattron(dirwin->window, A_REVERSE); memcpy(sbuf, name + sindex, strlen(searchq)); sbuf[strlen(searchq)] = '\0'; mvwaddstr(dirwin->window, y, x+sindex, sbuf); - wattroff(dirwin->window, COLOR_PAIR(COLOR_RED)); + wattroff(dirwin->window, COLOR_PAIR(SEARCH_MATCH_COLOR)); if (dirwin->usehighlight && dirwin->highlight == i) wattroff(dirwin->window, A_REVERSE); } @@ -515,6 +523,8 @@ print_win(DirWin *dirwin) static void update_child_win() { + char pathbuf[PATH_MAX]; + if (curwin.filecount <= 0) { free_dirwin(&childwin); return; @@ -524,6 +534,10 @@ update_child_win() switch (curwin.winfiles[curwin.highlight].d_type) { case DT_LNK: + if (access(get_fullpath(pathbuf, &curwin, curwin.highlight), F_OK) != 0) { + set_win_message(&childwin, "Link no longer exists."); + break; + } if (is_dir(&curwin, curwin.highlight)) goto dir; else @@ -547,9 +561,9 @@ print_top_title() { move(0, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_YELLOW)); + attron(COLOR_PAIR(TOP_TITLE_COLOR)); printw("%s:%s/%s", userinfo->pw_name, curwin.path, curwin.winfiles[curwin.highlight].d_name); - attroff(COLOR_PAIR(COLOR_YELLOW)); + attroff(COLOR_PAIR(TOP_TITLE_COLOR)); } static void @@ -572,13 +586,13 @@ print_bot_title() move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_BLUE)); + attron(COLOR_PAIR(BOT_TITLE_COUNT_COLOR)); printw("(%d/%d) ", curwin.filecount == 0 ? 0 : curwin.highlight+1, curwin.filecount); - attroff(COLOR_PAIR(COLOR_BLUE)); + attroff(COLOR_PAIR(BOT_TITLE_COUNT_COLOR)); - attron(COLOR_PAIR(COLOR_RED)); + attron(COLOR_PAIR(BOT_TITLE_INFO_COLOR)); addstr(fileinf); - attroff(COLOR_PAIR(COLOR_RED)); + attroff(COLOR_PAIR(BOT_TITLE_INFO_COLOR)); } static char * @@ -726,13 +740,18 @@ combo_key(int keypress) static void combo_go(int key) { + char pathbuf[PATH_MAX]; + switch (key) { case KEY_COMBO_GO_TOP: move_top(&curwin); update_child_win(); break; case KEY_COMBO_GO_HOME: - change_dir(userinfo->pw_dir, HOME, FALSE); + change_dir(userinfo->pw_dir, OTHER, FALSE); + break; + case KEY_COMBO_GO_ACCESS: + change_dir(replace_home(pathbuf, LN_ACCESS_DIR), OTHER, FALSE); break; default: break; @@ -815,10 +834,8 @@ change_dir(char *chdname, Direction direction, bool abspath) case LEFT: curwin.highlight = parwin.highlight; break; - case HOME: - curwin.highlight = 0; - break; default: + curwin.highlight = 0; break; } @@ -927,9 +944,9 @@ search() move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_MAGENTA)); + attron(COLOR_PAIR(PROMPT_COLOR)); addstr("Search name? "); - attroff(COLOR_PAIR(COLOR_MAGENTA)); + attroff(COLOR_PAIR(PROMPT_COLOR)); echo(); curs_set(1); @@ -1178,9 +1195,9 @@ make_dir(char *path) move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_MAGENTA)); + attron(COLOR_PAIR(PROMPT_COLOR)); addstr("Name of directory? "); - attroff(COLOR_PAIR(COLOR_MAGENTA)); + attroff(COLOR_PAIR(PROMPT_COLOR)); echo(); curs_set(1); @@ -1200,9 +1217,9 @@ make_file(char *path) move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_MAGENTA)); + attron(COLOR_PAIR(PROMPT_COLOR)); addstr("Name of file? "); - attroff(COLOR_PAIR(COLOR_MAGENTA)); + attroff(COLOR_PAIR(PROMPT_COLOR)); echo(); curs_set(1); @@ -1213,7 +1230,7 @@ make_file(char *path) if (strlen(name) > 0) { if ((fptr = fopen(name, "w")) == NULL) fatal("Error opening file '%s'\n", name); - fclose(fptr); + fclose(fptr); } } @@ -1230,9 +1247,9 @@ rm_file(char *fname) move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_MAGENTA)); + attron(COLOR_PAIR(PROMPT_COLOR)); printw("Remove %s? (y/N) ", fname); - attroff(COLOR_PAIR(COLOR_MAGENTA)); + attroff(COLOR_PAIR(PROMPT_COLOR)); echo(); curs_set(1); @@ -1279,9 +1296,9 @@ rename_file(char *fname) move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_MAGENTA)); + attron(COLOR_PAIR(PROMPT_COLOR)); addstr("New name? "); - attroff(COLOR_PAIR(COLOR_MAGENTA)); + attroff(COLOR_PAIR(PROMPT_COLOR)); echo(); curs_set(1); @@ -1305,9 +1322,9 @@ make_mod() move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_MAGENTA)); + attron(COLOR_PAIR(PROMPT_COLOR)); addstr("File mods (numeric)? "); - attroff(COLOR_PAIR(COLOR_MAGENTA)); + attroff(COLOR_PAIR(PROMPT_COLOR)); echo(); curs_set(1); @@ -1352,9 +1369,9 @@ exe_selection(SelAction action, char *askn) move(maxy-1, 0); clrtoeol(); - attron(COLOR_PAIR(COLOR_MAGENTA)); + attron(COLOR_PAIR(PROMPT_COLOR)); printw("%s selection (%d files) ? (y/N) ", askn, selc); - attroff(COLOR_PAIR(COLOR_MAGENTA)); + attroff(COLOR_PAIR(PROMPT_COLOR)); echo(); curs_set(1); @@ -1369,15 +1386,15 @@ exe_selection(SelAction action, char *askn) switch (action) { case COPY: for (size_t i = 0; i <selc; i++) - run_command(size, "cp -rf %s %s", selected[i], curwin.path); + run_command(size, "cp -rf %s %s", selected[i], curwin.path); break; case REMOVE: for (size_t i = 0; i <selc; i++) - run_command(size, "rm -rf %s", selected[i]); + run_command(size, "rm -rf %s", selected[i]); break; case MOVE: for (size_t i = 0; i <selc; i++) - run_command(size, "mv %s %s", selected[i], curwin.path); + run_command(size, "mv %s %s", selected[i], curwin.path); break; default: break; @@ -1440,6 +1457,21 @@ get_fullpath(char *buf, DirWin *dirwin, size_t index) } static char * +replace_home(char *buf, char *path) +{ + char *envv = "$HOME"; + size_t hlen; + + if ((strstr(path, envv) != NULL)) { + hlen = strlen(userinfo->pw_dir); + memcpy(buf, userinfo->pw_dir, hlen); + buf[hlen] = '\0'; + strcat(buf, path + strlen(envv)); + } + return buf; +} + +static char * get_dirname(char *buf, char *path) { strcpy(buf, path); diff --git a/cex.h b/cex.h @@ -34,6 +34,7 @@ #define KEY_COMBO_GO 'g' #define KEY_COMBO_GO_TOP 'g' #define KEY_COMBO_GO_HOME 'h' +#define KEY_COMBO_GO_ACCESS 'a' #define KEY_COMBO_INF 'i' #define KEY_COMBO_INF_OPEN 'o' @@ -47,9 +48,20 @@ #define KEY_COMBO_MAKE_MOD 'm' #define KEY_COMBO_MAKE_ACCESS 'a' +#define DIR_COLOR COLOR_BLUE +#define LN_COLOR COLOR_CYAN +#define INVALID_LN_COLOR COLOR_RED +#define SEARCH_MATCH_COLOR COLOR_YELLOW +#define TOP_TITLE_COLOR COLOR_YELLOW +#define BOT_TITLE_COUNT_COLOR COLOR_BLUE +#define BOT_TITLE_INFO_COLOR COLOR_RED +#define PROMPT_COLOR COLOR_MAGENTA +#define CHILDWIN_MESSAGE_COLOR COLOR_MAGENTA +#define MARK_SELECTED_COLOR COLOR_GREEN + #define ctrl(x) ((x) & 0x1f) -typedef enum {HOME, LEFT, RIGHT, UP, DOWN} Direction; +typedef enum {OTHER, LEFT, RIGHT, UP, DOWN} Direction; typedef enum {CURRENT, PARENT, CHILD} WinType; typedef enum {COPY, REMOVE, MOVE} SelAction; @@ -131,5 +143,6 @@ static int rename_file(); static char *get_file_info(char *buf, char *filepath); static char *get_fullpath(char *buf, DirWin *dirwin, size_t index); static char *get_dirname(char *buf, char *path); +static char *replace_home(char *buf, char *path); #endif