sfm

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

commit bfd368b6d2278d4ec79b84f9d1ab0d467e1378ff
parent 9cfee38c222f061d399a3dc95cb15e35cdbb4a34
Author: afify <hassan@afify.dev>
Date:   Sat,  4 Sep 2021 21:03:15 +0300

[feat] add duplicate file or dir

Diffstat:
MREADME.md | 51++++++++++++++++++++++++++-------------------------
Mconfig.def.h | 1+
Msfm.1 | 3+++
Msfm.c | 36+++++++++++++++++++++++++++++++++++-
4 files changed, 65 insertions(+), 26 deletions(-)

diff --git a/README.md b/README.md @@ -50,31 +50,32 @@ $ man sfm ``` **normal mode** -| key | description | -|:---------|:--------------------| -| `q` | quit | -| `h` | back | -| `j` | down | -| `k` | up | -| `l` | open | -| `g` | top | -| `G` | bottom | -| `M` | middle | -| `ctrl+u` | scroll up | -| `ctrl+d` | scroll down | -| `n` | create new file | -| `N` | create new dir | -| `d` | delete file \| dir | -| `y` | yank | -| `p` | paste | -| `P` | move | -| `c` | rename | -| `.` | toggle dotfiles | -| `v` | start visual mode | -| `/` | start filter | -| `ENTER` | find filter | -| `ESC` | exit filter | -| `SPACE` | switch pane | +| key | description | +|:---------|:-----------------------| +| `q` | quit | +| `h` | back | +| `j` | down | +| `k` | up | +| `l` | open | +| `g` | top | +| `G` | bottom | +| `M` | middle | +| `ctrl+u` | scroll up | +| `ctrl+d` | scroll down | +| `n` | create new file | +| `N` | create new dir | +| `d` | delete file \| dir | +| `D` | duplicate file \| dir | +| `y` | yank | +| `p` | paste | +| `P` | move | +| `c` | rename | +| `.` | toggle dotfiles | +| `v` | start visual mode | +| `/` | start filter | +| `ENTER` | find filter | +| `ESC` | exit filter | +| `SPACE` | switch pane | **visual mode** | key | description | diff --git a/config.def.h b/config.def.h @@ -85,6 +85,7 @@ static Key nkeys[] = { { {.ch = 'n'}, crnf, {0} }, { {.ch = 'N'}, crnd, {0} }, { {.ch = 'd'}, delent, {0} }, + { {.ch = 'D'}, dupl, {0} }, { {.ch = 'x'}, calcdir, {0} }, { {.ch = '/'}, start_filter, {0} }, { {.ch = 'q'}, quit, {0} }, diff --git a/sfm.1 b/sfm.1 @@ -51,6 +51,9 @@ create new directory if not exists .B d delete file | directory recursively .TP +.B D +duplicate file | directory recursively +.TP .B y yank .TP diff --git a/sfm.c b/sfm.c @@ -167,6 +167,7 @@ static void init_files(void); static void free_files(void); static void yank(const Arg *arg); static void rname(const Arg *arg); +static void dupl(const Arg *arg); static void switch_pane(const Arg *arg); static void quit(const Arg *arg); static void grabkeys(struct tb_event *, Key *, size_t); @@ -318,7 +319,8 @@ print_row(Pane *pane, size_t entpos, Cpair col) if (S_ISLNK(pane->direntr[entpos].mode) != 0) { rez_pth = ecalloc(MAX_P, sizeof(char)); if (realpath(pane->direntr[entpos].name, rez_pth) != NULL) { - snprintf(lnk_full, MAX_N, "%s -> %s", full_str, rez_pth); + snprintf( + lnk_full, MAX_N, "%s -> %s", full_str, rez_pth); full_str = lnk_full; } free(rez_pth); @@ -1416,6 +1418,38 @@ rname(const Arg *arg) } static void +dupl(const Arg *arg) +{ + if (cpane->dirc < 1) + return; + char new_name[MAX_P]; + char *input_name; + + input_name = ecalloc(MAX_N, sizeof(char)); + + if (get_usrinput(input_name, MAX_N, "new name: %s", + basename(CURSOR(cpane).name)) < 0) { + free(input_name); + return; + } + + if (snprintf(new_name, MAX_P, "%s/%s", cpane->dirn, input_name) < 0) { + free(input_name); + print_error(strerror(errno)); + return; + } + + char *tmp[1]; + tmp[0] = CURSOR(cpane).name; + if (spawn(cp_cmd, cp_cmd_len, tmp, 1, new_name, DontWait) < 0) { + print_error(strerror(errno)); + return; + } + + free(input_name); +} + +static void yank(const Arg *arg) { if (cpane->dirc < 1)