sfm

Simple file manager
git clone git://git.christosmarg.xyz/sfm.git
Log | Files | Refs | README | LICENSE

commit ce3019cd9f660c0b6f0ad6ad61b62cf1fc3616f1
parent ecff47de281537710ed380499372ff817ac94865
Author: Christos Margiolis <christos@margiolis.net>
Date:   Mon, 23 Nov 2020 00:40:50 +0200

add basic sorting

Diffstat:
Mconfig.h | 8++++----
Msfm.c | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
2 files changed, 83 insertions(+), 30 deletions(-)

diff --git a/config.h b/config.h @@ -57,21 +57,21 @@ static Key keys[] = { { 0, 'k', nav, {.n = NAV_UP} }, { 0, KEY_DOWN, nav, {.n = NAV_DOWN} }, { 0, 'j', nav, {.n = NAV_DOWN} }, - { 'g', 'g', nav, {.n = NAV_TOP} }, + { 0, 'g', nav, {.n = NAV_TOP} }, { 0, 'G', nav, {.n = NAV_BOTTOM} }, { 0, '.', nav, {.n = NAV_SHOWALL} }, { 0, 'f', nav, {.n = NAV_FPREVIEW} }, { 0, 'i', nav, {.n = NAV_INFO} }, - //{ 0, 'r', nav, {.n = NAV_REDRAW} }, - { 'g', 'u', cd, {.s = "/usr"} }, + { 0, CTRL('r'), nav, {.n = NAV_REDRAW} }, { 0, '~', cd, {.s = "/home/christos"} }, - { 'g', 'n', cd, {.s = "/mnt/christos_ntfs/christos"} }, + { 0, CTRL('n'), cd, {.s = "/mnt/christos_ntfs/christos"} }, { 0, ' ', selectitem, {.v = NULL} }, { 0, 'p', builtinrun, {.n = RUN_PAGER} }, { 0, 'e', builtinrun, {.n = RUN_EDITOR} }, { 0, 'o', builtinrun, {.n = RUN_OPENWITH} }, { 0, 'r', builtinrun, {.n = RUN_RENAME} }, { 0, 'x', run, SHCMD("rm -rf") }, + { 0, 's', sort, {.v = NULL} }, { 0, ':', prompt, {.v = NULL} }, { 0, 'q', quit, {.v = NULL} }, }; diff --git a/sfm.c b/sfm.c @@ -14,27 +14,39 @@ #include <ncurses.h> #ifndef PATH_MAX -#define PATH_MAX 1024 +#define PATH_MAX 1024 #endif /* PATH_MAX */ #ifndef HOST_NAME_MAX -#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX #endif /* HOST_NAME_MAX */ #ifndef LOGIN_NAME_MAX -#define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX +#define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX #endif /* LOGIN_NAME_MAX */ + #ifndef DT_DIR -#define DT_DIR 4 +#define DT_DIR 4 #endif /* DT_DIR */ #ifndef DT_REG -#define DT_REG 8 +#define DT_REG 8 #endif /* DT_REG */ +#ifndef ESC +#define ESC 27 +#endif + +#ifndef DEL +#define DEL 127 +#endif + +#define CTRL(x) ((x) & 0x1f) #define YMAX (getmaxy(stdscr)) #define XMAX (getmaxx(stdscr)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y)) #define ARRLEN(x) (sizeof(x) / sizeof(x[0])) #define ISDIGIT(x) ((unsigned int)(x) - '0' <= 9) +#define ENTSORT(e, n) (qsort((e), (n), sizeof(*(e)), sortfn)) + #define SEL_CORRECT \ win->sel = ((win->sel < 0) ? 0 : (win->sel > win->nf - 1) \ ? win->nf - 1 : win->sel); @@ -114,36 +126,40 @@ enum { MSG_OPENWITH, MSG_RENAME, MSG_EXEC, + MSG_SORT, MSG_PROMPT, }; -/* globals */ -static Win *win = NULL; /* main display */ -static char *curdir = NULL; /* current directory */ -static uchar f_showall = 0; /* show hidden files */ -static uchar f_redraw = 0; /* redraw screen */ -static uchar f_fpreview = 0; /* preview files */ -static uchar f_info = 0; /* show info about entries */ - -static char *cmds[] = { +/* useful strings */ +static const char *cmds[] = { [CMD_OPEN] = "xdg-open", [CMD_MV] = "mv", }; -static char *envs[] = { +static const char *envs[] = { [ENV_SHELL] = "SHELL", [ENV_EDITOR] = "EDITOR", [ENV_PAGER] = "PAGER", }; -static char *msgs[] = { +static const char *msgs[] = { [MSG_OPENWITH] = "open with: ", [MSG_RENAME] = "rename: ", [MSG_EXEC] = "execute %s (y/n)?", + [MSG_SORT] = "'n'ame 's'ize 'r'everse", [MSG_PROMPT] = ":", }; +/* globals variables */ +static Win *win = NULL; /* main display */ +static char *curdir = NULL; /* current directory */ +static uchar f_showall = 0; /* show hidden files */ +static uchar f_redraw = 0; /* redraw screen */ +static uchar f_fpreview = 0; /* preview files */ +static uchar f_info = 0; /* show info about entries */ + /* function pointers */ +static int (*sortfn)(const void *x, const void *y); /* function declarations */ static void cursesinit(void); @@ -160,6 +176,7 @@ static void nav(const Arg *); static void cd(const Arg *); static void run(const Arg *); static void builtinrun(const Arg *); +static void sort(const Arg *); static void prompt(const Arg *); static void selectitem(const Arg *); static void quit(const Arg *); @@ -170,6 +187,25 @@ static void die(const char *, ...); #include "config.h" /* function implementations */ +static inline int +sortname(const void *x, const void *y) +{ + return (strcmp(((Entry *)x)->name, ((Entry *)y)->name)); +} + +static inline int +sortsize(const void *x, const void *y) +{ + return -(((Entry *)x)->stat.st_size - ((Entry *)y)->stat.st_size); +} + +/* TODO fix */ +static inline int +sortrev(const void *x, const void *y) +{ + return -sortfn(x, y); +} + void cursesinit(void) { @@ -258,6 +294,7 @@ entget(char *path, ulong n) } (void)closedir(dir); + ENTSORT(ents, n); return ents; } @@ -358,7 +395,8 @@ promptstr(const char *msg) case KEY_BACKSPACE: /* FALLTHROUGH */ case KEY_DC: /* FALLTHROUGH */ case '\b': /* FALLTHROUGH */ - len--; + if (len > 0) + len--; break; /*case ESC:*/ /*break;*/ @@ -377,7 +415,6 @@ promptstr(const char *msg) return str; } -/* TODO: replace it, i don't like it. */ int confirmact(const char *str) { @@ -388,6 +425,7 @@ confirmact(const char *str) return (getch() == 'y'); } +/*TODO: make int */ void spawn(char *cmd) { @@ -415,7 +453,6 @@ spawn(char *cmd) } } -/*TODO: handle user given shell cmds*/ void nav(const Arg *arg) { @@ -533,6 +570,27 @@ end: } void +sort(const Arg *arg) +{ + move(YMAX - 1, 0); + clrtoeol(); + mvprintw(YMAX - 1, 0, msgs[MSG_SORT]); + refresh(); + switch (getch()) { + case 'n': + sortfn = sortname; + break; + case 's': + sortfn = sortsize; + break; + case 'r': + /*sortfn = sortrev;*/ + break; + } + ENTSORT(win->ents, win->nf); +} + +void prompt(const Arg *arg) { char buf[BUFSIZ]; @@ -602,6 +660,7 @@ main(int argc, char *argv[]) cursesinit(); f_redraw = 1; + sortfn = sortname; for (;;) { erase(); @@ -623,16 +682,10 @@ main(int argc, char *argv[]) if (f_fpreview) filepreview(); - /*TODO: what the hell?*/ c = getch(); - for (i = 0; i < ARRLEN(keys); i++) { - if (c == keys[i].mod) { - mvaddch(YMAX - 1, 0, c); - c = getch(); - } + for (i = 0; i < ARRLEN(keys); i++) if (c == keys[i].key) keys[i].func(&(keys[i].arg)); - } } return 0;