From 746e5d0d1f47d715a3068ac1e93fdb38fc4d2f78 Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Fri, 1 Mar 2019 06:46:13 +0530 Subject: [PATCH] Fix #141, #196 --- README.md | 4 +++- nnn.1 | 5 +++- src/nnn.c | 71 +++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 3dbc27f1..bfba745b 100644 --- a/README.md +++ b/README.md @@ -318,7 +318,9 @@ To copy multiple absolute file paths: - press ^Y (or Y) to enter selection mode. In this mode it's possible to - cherry-pick individual files one by one by pressing ^K on each entry (works across directories and contexts); or, - navigate to another file in the same directory to select a range of files -- press ^Y (or Y) _again_ to copy the paths and exit the selection mode +- press ^Y again to save the selection and exit selection mode. + +Selected files are visually indicated by a `+`. The files in the list can now be copied (P), moved (V) or removed (X). diff --git a/nnn.1 b/nnn.1 index 8bed5b1b..8617a4d4 100644 --- a/nnn.1 +++ b/nnn.1 @@ -265,7 +265,10 @@ In this mode it's possible to .br (2) navigate to another file in the same directory to select a range of files. .Pp -Pressing \fI^Y\fR again saves the selection to the list and exits the selection mode. +Press \fI^Y\fR again to save the selection and exit selection mode. +.Pp +Selected files are visually indicated by a \fB+\fR. +.br The files in the list can now be copied, moved or removed using respective keyboard shortcuts. .Pp To list the selected files press \fIy\fR. diff --git a/src/nnn.c b/src/nnn.c index 4e208d6e..8951eb70 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -184,12 +184,15 @@ disabledbg() #define DESCRIPTOR_LEN 32 #define _ALIGNMENT 0x10 /* 16-byte alignment */ #define _ALIGNMENT_MASK 0xF -#define DIR_OR_LINK_TO_DIR 0x1 #define HOME_LEN_MAX 64 #define CTX_MAX 4 #define DOT_FILTER_LEN 7 #define ASCII_MAX 128 +/* Entry flags */ +#define DIR_OR_LINK_TO_DIR 0x1 +#define FILE_COPIED 0x10 + /* Macros to define process spawn behaviour as flags */ #define F_NONE 0x00 /* no flag set */ #define F_MARKER 0x01 /* draw marker to indicate nnn spawned (e.g. shell) */ @@ -909,6 +912,17 @@ static bool cpsafe(void) return TRUE; } +/* Reset copy indicators */ +static void resetcpind() +{ + int r = 0; + + /* Reset copy indicators */ + for (; r < ndents; ++r) + if (dents[r].flags & FILE_COPIED) + dents[r].flags &= ~FILE_COPIED; +} + /* Initialize curses mode */ static bool initcurses(void) { @@ -1977,7 +1991,7 @@ static void printent(const struct entry *ent, int sel, uint namecols) static void printent_long(const struct entry *ent, int sel, uint namecols) { - char timebuf[18], permbuf[4]; + char timebuf[18], permbuf[4], cp = ' '; /* Timestamp */ strftime(timebuf, 18, "%F %R", localtime(&ent->t)); @@ -1985,6 +1999,10 @@ static void printent_long(const struct entry *ent, int sel, uint namecols) /* Permissions */ snprintf(permbuf, 4, "%d%d%d", (ent->mode >> 6) & 7, (ent->mode >> 3) & 7, ent->mode & 7); + /* Add copy indicator */ + if (ent->flags & FILE_COPIED) + cp = '+'; + /* Trim escape chars from name */ const char *pname = unescape(ent->name, namecols); @@ -1997,39 +2015,39 @@ static void printent_long(const struct entry *ent, int sel, uint namecols) switch (ent->mode & S_IFMT) { case S_IFREG: if (ent->mode & 0100) - printw(" %-16.16s 0%s %8.8s* %s*\n", timebuf, permbuf, + printw("%c%-16.16s 0%s %8.8s* %s*\n", cp, timebuf, permbuf, coolsize(cfg.blkorder ? ent->blocks << BLK_SHIFT : ent->size), pname); else - printw(" %-16.16s 0%s %8.8s %s\n", timebuf, permbuf, + printw("%c%-16.16s 0%s %8.8s %s\n", cp, timebuf, permbuf, coolsize(cfg.blkorder ? ent->blocks << BLK_SHIFT : ent->size), pname); break; case S_IFDIR: if (cfg.blkorder) - printw(" %-16.16s 0%s %8.8s/ %s/\n", - timebuf, permbuf, coolsize(ent->blocks << BLK_SHIFT), pname); + printw("%c%-16.16s 0%s %8.8s/ %s/\n", + cp, timebuf, permbuf, coolsize(ent->blocks << BLK_SHIFT), pname); else - printw(" %-16.16s 0%s / %s/\n", timebuf, permbuf, pname); + printw("%c%-16.16s 0%s / %s/\n", cp, timebuf, permbuf, pname); break; case S_IFLNK: if (ent->flags & DIR_OR_LINK_TO_DIR) - printw(" %-16.16s 0%s @/ %s@\n", timebuf, permbuf, pname); + printw("%c%-16.16s 0%s @/ %s@\n", cp, timebuf, permbuf, pname); else - printw(" %-16.16s 0%s @ %s@\n", timebuf, permbuf, pname); + printw("%c%-16.16s 0%s @ %s@\n", cp, timebuf, permbuf, pname); break; case S_IFSOCK: - printw(" %-16.16s 0%s = %s=\n", timebuf, permbuf, pname); + printw("%c%-16.16s 0%s = %s=\n", cp, timebuf, permbuf, pname); break; case S_IFIFO: - printw(" %-16.16s 0%s | %s|\n", timebuf, permbuf, pname); + printw("%c%-16.16s 0%s | %s|\n", cp, timebuf, permbuf, pname); break; case S_IFBLK: - printw(" %-16.16s 0%s b %s\n", timebuf, permbuf, pname); + printw("%c%-16.16s 0%s b %s\n", cp, timebuf, permbuf, pname); break; case S_IFCHR: - printw(" %-16.16s 0%s c %s\n", timebuf, permbuf, pname); + printw("%c%-16.16s 0%s c %s\n", cp, timebuf, permbuf, pname); break; default: - printw(" %-16.16s 0%s %8.8s? %s?\n", timebuf, permbuf, + printw("%c%-16.16s 0%s %8.8s? %s?\n", cp, timebuf, permbuf, coolsize(cfg.blkorder ? ent->blocks << BLK_SHIFT : ent->size), pname); break; } @@ -2609,6 +2627,7 @@ static int dentfill(char *path, struct entry **dents) dentp->mode = sb.st_mode; dentp->t = sb.st_mtime; dentp->size = sb.st_size; + dentp->flags = 0; if (cfg.blkorder) { if (S_ISDIR(sb.st_mode)) { @@ -2646,8 +2665,6 @@ static int dentfill(char *path, struct entry **dents) if (S_ISDIR(sb.st_mode)) dentp->flags |= DIR_OR_LINK_TO_DIR; - else if (dentp->flags & DIR_OR_LINK_TO_DIR) - dentp->flags &= ~DIR_OR_LINK_TO_DIR; ++n; } @@ -3463,8 +3480,13 @@ nochange: ++ncp; } else { r = mkpath(path, dents[cur].name, newpath); - /* Keep the copy buf in sync */ - copybufpos = 0; + + if (copybufpos) { + resetcpind(); + + /* Keep the copy buf in sync */ + copybufpos = 0; + } appendfpath(newpath, r); writecp(newpath, r - 1); /* Truncate NULL from end */ @@ -3472,14 +3494,20 @@ nochange: spawn(copier, NULL, NULL, NULL, F_NOTRACE); } + dents[cur].flags |= FILE_COPIED; + printmsg(newpath); goto nochange; case SEL_COPYMUL: cfg.copymode ^= 1; if (cfg.copymode) { + if (copybufpos) { + resetcpind(); + writecp(NULL, 0); + copybufpos = 0; + } g_crc = crc8fast((uchar *)dents, ndents * sizeof(struct entry)); copystartid = cur; - copybufpos = 0; ncp = 0; printmsg("selection on"); DPRINTF_S("selection on"); @@ -3516,11 +3544,14 @@ nochange: } if ((!ncp && copystartid < copyendid) || sel == SEL_COPYALL) { - for (r = copystartid; r <= copyendid; ++r) + for (r = copystartid; r <= copyendid; ++r) { if (!appendfpath(newpath, mkpath(path, dents[r].name, newpath))) goto nochange; + dents[r].flags |= FILE_COPIED; + } + mvprintw(LINES - 1, 0, "%d files selected\n", copyendid - copystartid + 1); }