mirror of
https://github.com/jarun/nnn.git
synced 2024-11-24 11:51:27 +00:00
parent
4c8c916ca3
commit
746e5d0d1f
|
@ -318,7 +318,9 @@ To copy multiple absolute file paths:
|
||||||
- press <kbd>^Y</kbd> (or <kbd>Y</kbd>) to enter selection mode. In this mode it's possible to
|
- press <kbd>^Y</kbd> (or <kbd>Y</kbd>) to enter selection mode. In this mode it's possible to
|
||||||
- cherry-pick individual files one by one by pressing <kbd>^K</kbd> on each entry (works across directories and contexts); or,
|
- cherry-pick individual files one by one by pressing <kbd>^K</kbd> on each entry (works across directories and contexts); or,
|
||||||
- navigate to another file in the same directory to select a range of files
|
- navigate to another file in the same directory to select a range of files
|
||||||
- press <kbd>^Y</kbd> (or <kbd>Y</kbd>) _again_ to copy the paths and exit the selection mode
|
- press <kbd>^Y</kbd> 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 (<kbd>P</kbd>), moved (<kbd>V</kbd>) or removed (<kbd>X</kbd>).
|
The files in the list can now be copied (<kbd>P</kbd>), moved (<kbd>V</kbd>) or removed (<kbd>X</kbd>).
|
||||||
|
|
||||||
|
|
5
nnn.1
5
nnn.1
|
@ -265,7 +265,10 @@ In this mode it's possible to
|
||||||
.br
|
.br
|
||||||
(2) navigate to another file in the same directory to select a range of files.
|
(2) navigate to another file in the same directory to select a range of files.
|
||||||
.Pp
|
.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.
|
The files in the list can now be copied, moved or removed using respective keyboard shortcuts.
|
||||||
.Pp
|
.Pp
|
||||||
To list the selected files press \fIy\fR.
|
To list the selected files press \fIy\fR.
|
||||||
|
|
71
src/nnn.c
71
src/nnn.c
|
@ -184,12 +184,15 @@ disabledbg()
|
||||||
#define DESCRIPTOR_LEN 32
|
#define DESCRIPTOR_LEN 32
|
||||||
#define _ALIGNMENT 0x10 /* 16-byte alignment */
|
#define _ALIGNMENT 0x10 /* 16-byte alignment */
|
||||||
#define _ALIGNMENT_MASK 0xF
|
#define _ALIGNMENT_MASK 0xF
|
||||||
#define DIR_OR_LINK_TO_DIR 0x1
|
|
||||||
#define HOME_LEN_MAX 64
|
#define HOME_LEN_MAX 64
|
||||||
#define CTX_MAX 4
|
#define CTX_MAX 4
|
||||||
#define DOT_FILTER_LEN 7
|
#define DOT_FILTER_LEN 7
|
||||||
#define ASCII_MAX 128
|
#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 */
|
/* Macros to define process spawn behaviour as flags */
|
||||||
#define F_NONE 0x00 /* no flag set */
|
#define F_NONE 0x00 /* no flag set */
|
||||||
#define F_MARKER 0x01 /* draw marker to indicate nnn spawned (e.g. shell) */
|
#define F_MARKER 0x01 /* draw marker to indicate nnn spawned (e.g. shell) */
|
||||||
|
@ -909,6 +912,17 @@ static bool cpsafe(void)
|
||||||
return TRUE;
|
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 */
|
/* Initialize curses mode */
|
||||||
static bool initcurses(void)
|
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)
|
static void printent_long(const struct entry *ent, int sel, uint namecols)
|
||||||
{
|
{
|
||||||
char timebuf[18], permbuf[4];
|
char timebuf[18], permbuf[4], cp = ' ';
|
||||||
|
|
||||||
/* Timestamp */
|
/* Timestamp */
|
||||||
strftime(timebuf, 18, "%F %R", localtime(&ent->t));
|
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 */
|
/* Permissions */
|
||||||
snprintf(permbuf, 4, "%d%d%d", (ent->mode >> 6) & 7, (ent->mode >> 3) & 7, ent->mode & 7);
|
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 */
|
/* Trim escape chars from name */
|
||||||
const char *pname = unescape(ent->name, namecols);
|
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) {
|
switch (ent->mode & S_IFMT) {
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
if (ent->mode & 0100)
|
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);
|
coolsize(cfg.blkorder ? ent->blocks << BLK_SHIFT : ent->size), pname);
|
||||||
else
|
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);
|
coolsize(cfg.blkorder ? ent->blocks << BLK_SHIFT : ent->size), pname);
|
||||||
break;
|
break;
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
if (cfg.blkorder)
|
if (cfg.blkorder)
|
||||||
printw(" %-16.16s 0%s %8.8s/ %s/\n",
|
printw("%c%-16.16s 0%s %8.8s/ %s/\n",
|
||||||
timebuf, permbuf, coolsize(ent->blocks << BLK_SHIFT), pname);
|
cp, timebuf, permbuf, coolsize(ent->blocks << BLK_SHIFT), pname);
|
||||||
else
|
else
|
||||||
printw(" %-16.16s 0%s / %s/\n", timebuf, permbuf, pname);
|
printw("%c%-16.16s 0%s / %s/\n", cp, timebuf, permbuf, pname);
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
if (ent->flags & DIR_OR_LINK_TO_DIR)
|
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
|
else
|
||||||
printw(" %-16.16s 0%s @ %s@\n", timebuf, permbuf, pname);
|
printw("%c%-16.16s 0%s @ %s@\n", cp, timebuf, permbuf, pname);
|
||||||
break;
|
break;
|
||||||
case S_IFSOCK:
|
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;
|
break;
|
||||||
case S_IFIFO:
|
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;
|
break;
|
||||||
case S_IFBLK:
|
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;
|
break;
|
||||||
case S_IFCHR:
|
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;
|
break;
|
||||||
default:
|
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);
|
coolsize(cfg.blkorder ? ent->blocks << BLK_SHIFT : ent->size), pname);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2609,6 +2627,7 @@ static int dentfill(char *path, struct entry **dents)
|
||||||
dentp->mode = sb.st_mode;
|
dentp->mode = sb.st_mode;
|
||||||
dentp->t = sb.st_mtime;
|
dentp->t = sb.st_mtime;
|
||||||
dentp->size = sb.st_size;
|
dentp->size = sb.st_size;
|
||||||
|
dentp->flags = 0;
|
||||||
|
|
||||||
if (cfg.blkorder) {
|
if (cfg.blkorder) {
|
||||||
if (S_ISDIR(sb.st_mode)) {
|
if (S_ISDIR(sb.st_mode)) {
|
||||||
|
@ -2646,8 +2665,6 @@ static int dentfill(char *path, struct entry **dents)
|
||||||
|
|
||||||
if (S_ISDIR(sb.st_mode))
|
if (S_ISDIR(sb.st_mode))
|
||||||
dentp->flags |= DIR_OR_LINK_TO_DIR;
|
dentp->flags |= DIR_OR_LINK_TO_DIR;
|
||||||
else if (dentp->flags & DIR_OR_LINK_TO_DIR)
|
|
||||||
dentp->flags &= ~DIR_OR_LINK_TO_DIR;
|
|
||||||
|
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
@ -3463,8 +3480,13 @@ nochange:
|
||||||
++ncp;
|
++ncp;
|
||||||
} else {
|
} else {
|
||||||
r = mkpath(path, dents[cur].name, newpath);
|
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);
|
appendfpath(newpath, r);
|
||||||
|
|
||||||
writecp(newpath, r - 1); /* Truncate NULL from end */
|
writecp(newpath, r - 1); /* Truncate NULL from end */
|
||||||
|
@ -3472,14 +3494,20 @@ nochange:
|
||||||
spawn(copier, NULL, NULL, NULL, F_NOTRACE);
|
spawn(copier, NULL, NULL, NULL, F_NOTRACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dents[cur].flags |= FILE_COPIED;
|
||||||
|
|
||||||
printmsg(newpath);
|
printmsg(newpath);
|
||||||
goto nochange;
|
goto nochange;
|
||||||
case SEL_COPYMUL:
|
case SEL_COPYMUL:
|
||||||
cfg.copymode ^= 1;
|
cfg.copymode ^= 1;
|
||||||
if (cfg.copymode) {
|
if (cfg.copymode) {
|
||||||
|
if (copybufpos) {
|
||||||
|
resetcpind();
|
||||||
|
writecp(NULL, 0);
|
||||||
|
copybufpos = 0;
|
||||||
|
}
|
||||||
g_crc = crc8fast((uchar *)dents, ndents * sizeof(struct entry));
|
g_crc = crc8fast((uchar *)dents, ndents * sizeof(struct entry));
|
||||||
copystartid = cur;
|
copystartid = cur;
|
||||||
copybufpos = 0;
|
|
||||||
ncp = 0;
|
ncp = 0;
|
||||||
printmsg("selection on");
|
printmsg("selection on");
|
||||||
DPRINTF_S("selection on");
|
DPRINTF_S("selection on");
|
||||||
|
@ -3516,11 +3544,14 @@ nochange:
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!ncp && copystartid < copyendid) || sel == SEL_COPYALL) {
|
if ((!ncp && copystartid < copyendid) || sel == SEL_COPYALL) {
|
||||||
for (r = copystartid; r <= copyendid; ++r)
|
for (r = copystartid; r <= copyendid; ++r) {
|
||||||
if (!appendfpath(newpath, mkpath(path,
|
if (!appendfpath(newpath, mkpath(path,
|
||||||
dents[r].name, newpath)))
|
dents[r].name, newpath)))
|
||||||
goto nochange;
|
goto nochange;
|
||||||
|
|
||||||
|
dents[r].flags |= FILE_COPIED;
|
||||||
|
}
|
||||||
|
|
||||||
mvprintw(LINES - 1, 0, "%d files selected\n",
|
mvprintw(LINES - 1, 0, "%d files selected\n",
|
||||||
copyendid - copystartid + 1);
|
copyendid - copystartid + 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue