sfm

simple file manager
git clone https://git.afify.dev/sfm.git
Log | Files | Refs | README | LICENSE

commit fc58bc50bf165d2ed5efd1dd3ae2e9d4f5f2d4f3
parent ab67e2e56f7eb99b7172b4cca689cb67d87405e4
Author: afify <hassan@afify.dev>
Date:   Tue, 25 May 2021 01:26:18 +0300

[ref] spawn & Rule

- Rule will take array len (remove NULL ended array)
        - extensions len is calculated at compile time

- spawn() will take 2 arrays and 1 char* :
        - array of commands
        - array of files

- use cp_cmd ... in visual mode

Diffstat:
Mconfig.def.h | 38+++++++++++++++++++++-----------------
Msfm.c | 106++++++++++++++++++++++++++++---------------------------------------------------
2 files changed, 59 insertions(+), 85 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -17,9 +17,13 @@ static const Cpair csearch = { 255, 0 }; static const Cpair cstatus = { 243, 0 }; /* commands */ -static const char *rm_cmd[] = { "rm", "-rf", NULL }; /* delete */ -static const char *cp_cmd[] = { "cp", "-r", yank_file, NULL }; /* copy */ -static const char *mv_cmd[] = { "mv", yank_file, NULL }; /* move */ +static const char *rm_cmd[] = { "rm", "-rf" }; /* delete */ +static const char *cp_cmd[] = { "cp", "-r" }; /* copy */ +static const char *mv_cmd[] = { "mv" }; /* move */ + +static const size_t rm_cmd_len = LEN(rm_cmd); +static const size_t cp_cmd_len = LEN(cp_cmd); +static const size_t mv_cmd_len = LEN(mv_cmd); /* bookmarks */ static Bookmark bmarks[] = { @@ -27,13 +31,13 @@ static Bookmark bmarks[] = { }; /* software */ -static const char *mpv[] = { "mpv", "--fullscreen", NULL }; -static const char *sxiv[] = { "sxiv", NULL }; -static const char *surf[] = { "surf", NULL }; -static const char *mupdf[] = { "mupdf", "-I", NULL }; -static const char *libreoffice[] = { "libreoffice", NULL }; -static const char *gimp[] = { "gimp", NULL }; -static const char *r2[] = { "r2", "-c", "vv", NULL }; +static const char *mpv[] = { "mpv", "--fullscreen" }; +static const char *sxiv[] = { "sxiv" }; +static const char *surf[] = { "surf" }; +static const char *mupdf[] = { "mupdf", "-I" }; +static const char *libreoffice[] = { "libreoffice" }; +static const char *gimp[] = { "gimp" }; +static const char *r2[] = { "r2", "-c", "vv" }; /* extensions*/ static const char *images[] = { "bmp", "jpg", "jpeg", "png", "gif", "xpm" }; @@ -48,13 +52,13 @@ static const char *documents[] = { "odt", "doc", "docx", "xls", "xlsx", "odp", "ods", "pptx", "odg" }; static Rule rules[] = { - {videos, LEN(videos), mpv}, - {images, LEN(images), sxiv}, - {web, LEN(web), surf}, - {pdf, LEN(pdf), mupdf}, - {documents, LEN(documents), libreoffice}, - {arts, LEN(arts), gimp}, - {obj, LEN(obj), r2}, + {videos, LEN(videos), mpv, LEN(mpv) }, + {images, LEN(images), sxiv, LEN(sxiv) }, + {web, LEN(web), surf, LEN(surf) }, + {pdf, LEN(pdf), mupdf, LEN(mupdf) }, + {documents, LEN(documents), libreoffice, LEN(libreoffice) }, + {arts, LEN(arts), gimp, LEN(gimp) }, + {obj, LEN(obj), r2, LEN(r2) }, }; /* normal keys */ diff --git a/sfm.c b/sfm.c @@ -93,6 +93,7 @@ typedef struct { const char **ext; size_t exlen; const void *v; + size_t vlen; } Rule; typedef union { @@ -152,7 +153,7 @@ static void scrup(void); static void scrups(void); static int get_usrinput(char *, size_t, const char *, ...); static int frules(char *); -static int spawn(const void *, char *); +static int spawn(const void *, size_t, const void *, size_t, char *); static int opnf(char *); static int fsev_init(void); static int addwatch(void); @@ -196,7 +197,7 @@ static char *editor[2]; static char fed[] = "vi"; static int theight, twidth, scrheight; static size_t selection_size = 0; -static char yank_file[MAX_P]; +static char *yank_file[MAX_P]; static int *selection; static int cont_vmode = 0; static char **selected_files; @@ -681,7 +682,7 @@ delent(char *fullpath) } free(inp_conf); - return spawn(rm_cmd, fullpath); + return spawn(rm_cmd, rm_cmd_len, yank_file, 1, fullpath); } static void @@ -1119,24 +1120,27 @@ frules(char *ex) } static int -spawn(const void *v, char *fn) +spawn(const void *com_argv, size_t com_argc, const void *f_argv, size_t f_argc, + char *fn) { - int ws, x, argc; + int ws; + size_t i, argc, x; pid_t pid, r; - x = 0; - argc = 0; + argc = com_argc + f_argc + 2; + x = com_argc; + char *argv[argc]; - /* count args */ - while (((char **)v)[x++] != NULL) - argc++; + for (i = 0; i < com_argc; i++) /* get command */ + argv[i] = ((char **)com_argv)[i]; - char *argv[argc + 2]; - for (x = 0; x < argc; x++) - argv[x] = ((char **)v)[x]; + for (i = 0; i < f_argc; i++) { /* get files */ + argv[x] = ((char **)f_argv)[i]; + x++; + } - argv[argc] = fn; - argv[argc + 1] = NULL; + argv[argc - 2] = fn; + argv[argc - 1] = NULL; pid = fork(); switch (pid) { @@ -1167,9 +1171,9 @@ opnf(char *fn) free(ex); if (c < 0) /* extension not found open in editor */ - return spawn(editor, fn); + return spawn(editor, 1, NULL, 0, fn); else - return spawn((char **)rules[c].v, fn); + return spawn((char **)rules[c].v, rules[c].vlen, NULL, 0, fn); } static int @@ -1452,7 +1456,6 @@ seldel(void) char *inp_conf; int conf_len = 4; char conf[] = "yes"; - size_t i; inp_conf = ecalloc(conf_len, sizeof(char)); if ((get_usrinput(inp_conf, conf_len, "delete file (yes) ?") < 0) || @@ -1464,24 +1467,13 @@ seldel(void) init_files(); - /* selected_files */ - char *seldel_cmd[selection_size + 3]; - seldel_cmd[0] = "rm"; - seldel_cmd[1] = "-rf"; - seldel_cmd[selection_size + 2] = NULL; - - /* add files to array */ - for (i = 2; i < selection_size + 2; i++) { - seldel_cmd[i] = selected_files[i - 2]; - } - - if (spawn(seldel_cmd, NULL) < 0) + if (spawn(rm_cmd, rm_cmd_len, selected_files, selection_size, NULL) < 0) print_error(strerror(errno)); else print_status(cprompt, "%zu files are deleted", selection_size); if (cpane->dirc > 0) - cpane->hdir = cpane->dirc - selection_size; + cpane->hdir = 1; free_files(); cont_vmode = -1; @@ -1490,14 +1482,13 @@ seldel(void) static void paste(void) { - size_t i; - if (strnlen(yank_file, MAX_P) != 0) { + if (yank_file[0] != NULL) { print_status(cprompt, "coping"); - if (spawn(cp_cmd, cpane->dirn) != 0) + if (spawn(cp_cmd, cp_cmd_len, &yank_file, 1, cpane->dirn) != 0) print_error(strerror(errno)); else print_status(cprompt, "file copied"); - yank_file[0] = '\0'; /* set yank_file len 0 */ + yank_file[0] = NULL; /* set yank_file len 0 */ return; } @@ -1506,18 +1497,8 @@ paste(void) if (selected_files == NULL) return; - /* selected_files */ - char *selcp_cmd[selection_size + 3]; - selcp_cmd[0] = "cp"; - selcp_cmd[1] = "-r"; - selcp_cmd[selection_size + 2] = NULL; - - /* add files to array */ - for (i = 2; i < selection_size + 2; i++) { - selcp_cmd[i] = selected_files[i - 2]; - } - - if (spawn(selcp_cmd, cpane->dirn) < 0) + if (spawn(cp_cmd, cp_cmd_len, selected_files, selection_size, + cpane->dirn) < 0) print_error(strerror(errno)); else print_status(cprompt, "%zu files are copied", selection_size); @@ -1528,15 +1509,13 @@ paste(void) static void selmv(void) { - size_t i; - - if (strnlen(yank_file, MAX_P) != 0) { + if (yank_file[0] != NULL) { print_status(cprompt, "moving"); - if (spawn(mv_cmd, cpane->dirn) != 0) + if (spawn(mv_cmd, mv_cmd_len, yank_file, 1, cpane->dirn) != 0) print_error(strerror(errno)); else print_status(cprompt, "file moved"); - yank_file[0] = '\0'; /* set yank_file len 0 */ + yank_file[0] = NULL; /* set yank_file len 0 */ return; } @@ -1545,18 +1524,8 @@ selmv(void) if (selected_files == NULL) return; - /* selected_files */ - char *selmv_cmd[selection_size + 3]; - selmv_cmd[0] = "mv"; - selmv_cmd[1] = "-r"; - selmv_cmd[selection_size + 2] = NULL; - - /* add files to array */ - for (i = 2; i < selection_size + 2; i++) { - selmv_cmd[i] = selected_files[i - 2]; - } - - if (spawn(selmv_cmd, cpane->dirn) < 0) + if (spawn(mv_cmd, mv_cmd_len, selected_files, selection_size, + cpane->dirn) < 0) print_error(strerror(errno)); else print_status(cprompt, "%zu files are moved", selection_size); @@ -1584,8 +1553,8 @@ rname(void) return; } - char *rename_cmd[] = { "mv", CURSOR.name, new_name, NULL }; - if (spawn(rename_cmd, NULL) < 0) + char *rename_cmd[] = { "mv", CURSOR.name, new_name }; + if (spawn(rename_cmd, 3, NULL, 0, NULL) < 0) print_error(strerror(errno)); free(input_name); @@ -1594,7 +1563,7 @@ rname(void) static void yank(void) { - strncpy(yank_file, CURSOR.name, MAX_P); + yank_file[0] = CURSOR.name; print_status(cprompt, "1 file is yanked", selection_size); } @@ -1750,7 +1719,8 @@ set_direntr(struct dirent *entry, DIR *dir, char *filter) free(tmpfull); i = 0; - cpane->direntr = erealloc(cpane->direntr, (10 + cpane->dirc) * sizeof(Entry)); + cpane->direntr = + erealloc(cpane->direntr, (10 + cpane->dirc) * sizeof(Entry)); while ((entry = readdir(dir)) != 0) { if ((strncmp(entry->d_name, ".", 2) == 0 || strncmp(entry->d_name, "..", 3) == 0))