mirror of
https://github.com/jarun/nnn.git
synced 2024-11-24 11:51:27 +00:00
Simplify selection
Update the selection buffer and file in-place: - Append file path when one is added. - Remember the last position in selection buffer at which the next filename is to be appended when a directory/context change happens (lastappendpos). So in case of a de-selection we can go back to that position and scan all the entries to add only the ones which are selected.
This commit is contained in:
parent
5a46b8fb25
commit
f73f79d5de
87
src/nnn.c
87
src/nnn.c
|
@ -596,7 +596,6 @@ static int dentfind(const char *fname, int n);
|
||||||
static void move_cursor(int target, int ignore_scrolloff);
|
static void move_cursor(int target, int ignore_scrolloff);
|
||||||
static inline bool getutil(char *util);
|
static inline bool getutil(char *util);
|
||||||
static size_t mkpath(const char *dir, const char *name, char *out);
|
static size_t mkpath(const char *dir, const char *name, char *out);
|
||||||
static void updateselbuf(const char *path, char *newpath);
|
|
||||||
static char *xgetenv(const char *name, char *fallback);
|
static char *xgetenv(const char *name, char *fallback);
|
||||||
static void plugscript(const char *plugin, char *newpath, uchar flags);
|
static void plugscript(const char *plugin, char *newpath, uchar flags);
|
||||||
|
|
||||||
|
@ -947,15 +946,12 @@ static size_t seltofile(int fd, uint *pcount)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List selection from selection buffer */
|
/* List selection from selection buffer */
|
||||||
static bool listselbuf(const char *path, char *newpath)
|
static bool listselbuf()
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
uint oldpos = selbufpos;
|
uint oldpos = selbufpos;
|
||||||
|
|
||||||
if (cfg.selmode)
|
|
||||||
updateselbuf(path, newpath);
|
|
||||||
|
|
||||||
if (!selbufpos)
|
if (!selbufpos)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1033,19 +1029,10 @@ static void updateselbuf(const char *path, char *newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish selection procedure before an operation */
|
/* Finish selection procedure before an operation */
|
||||||
static void endselection(const char *path, char *newpath)
|
static inline void endselection()
|
||||||
{
|
{
|
||||||
if (cfg.selmode) {
|
if (cfg.selmode)
|
||||||
cfg.selmode = 0;
|
cfg.selmode = 0;
|
||||||
|
|
||||||
updateselbuf(path, newpath);
|
|
||||||
|
|
||||||
if (selbufpos) { /* File path(s) written to the buffer */
|
|
||||||
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
|
|
||||||
if (cfg.x11)
|
|
||||||
plugscript(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearselection(void)
|
static void clearselection(void)
|
||||||
|
@ -4200,7 +4187,6 @@ static void browse(char *ipath, const char *session)
|
||||||
char rundir[PATH_MAX] __attribute__ ((aligned));
|
char rundir[PATH_MAX] __attribute__ ((aligned));
|
||||||
char runfile[NAME_MAX + 1] __attribute__ ((aligned));
|
char runfile[NAME_MAX + 1] __attribute__ ((aligned));
|
||||||
uchar opener_flags = (cfg.cliopener ? F_CLI : (F_NOTRACE | F_NOWAIT));
|
uchar opener_flags = (cfg.cliopener ? F_CLI : (F_NOTRACE | F_NOWAIT));
|
||||||
uint utmp;
|
|
||||||
int r = -1, fd, presel, selstartid = 0, selendid = 0;
|
int r = -1, fd, presel, selstartid = 0, selendid = 0;
|
||||||
ino_t inode = 0;
|
ino_t inode = 0;
|
||||||
enum action sel;
|
enum action sel;
|
||||||
|
@ -4209,7 +4195,7 @@ static void browse(char *ipath, const char *session)
|
||||||
char *path, *lastdir, *lastname, *dir, *tmp;
|
char *path, *lastdir, *lastname, *dir, *tmp;
|
||||||
MEVENT event;
|
MEVENT event;
|
||||||
struct timespec mousetimings[2] = {{.tv_sec = 0, .tv_nsec = 0}, {.tv_sec = 0, .tv_nsec = 0} };
|
struct timespec mousetimings[2] = {{.tv_sec = 0, .tv_nsec = 0}, {.tv_sec = 0, .tv_nsec = 0} };
|
||||||
bool currentmouse = 1, ctx_changed = FALSE;
|
bool currentmouse = 1;
|
||||||
|
|
||||||
atexit(dentfree);
|
atexit(dentfree);
|
||||||
|
|
||||||
|
@ -4241,10 +4227,8 @@ static void browse(char *ipath, const char *session)
|
||||||
errexit();
|
errexit();
|
||||||
|
|
||||||
begin:
|
begin:
|
||||||
if (cfg.selmode && lastdir[0] && !ctx_changed)
|
if (cfg.selmode && lastdir[0])
|
||||||
updateselbuf(lastdir, newpath);
|
lastappendpos = selbufpos;
|
||||||
else if (ctx_changed)
|
|
||||||
ctx_changed = FALSE;
|
|
||||||
|
|
||||||
#ifdef LINUX_INOTIFY
|
#ifdef LINUX_INOTIFY
|
||||||
if ((presel == FILTER || dir_changed) && inotify_wd >= 0) {
|
if ((presel == FILTER || dir_changed) && inotify_wd >= 0) {
|
||||||
|
@ -4328,10 +4312,8 @@ nochange:
|
||||||
if (r >= CTX_MAX)
|
if (r >= CTX_MAX)
|
||||||
sel = SEL_BACK;
|
sel = SEL_BACK;
|
||||||
else if (r >= 0 && r < CTX_MAX && r != cfg.curctx) {
|
else if (r >= 0 && r < CTX_MAX && r != cfg.curctx) {
|
||||||
if (cfg.selmode) {
|
if (cfg.selmode)
|
||||||
updateselbuf(path, newpath);
|
lastappendpos = selbufpos;
|
||||||
ctx_changed = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
savecurctx(&cfg, path, dents[cur].name, r);
|
savecurctx(&cfg, path, dents[cur].name, r);
|
||||||
|
|
||||||
|
@ -4453,8 +4435,7 @@ nochange:
|
||||||
{
|
{
|
||||||
/* If opened as vim plugin and Enter/^M pressed, pick */
|
/* If opened as vim plugin and Enter/^M pressed, pick */
|
||||||
if (cfg.picker && sel == SEL_GOIN) {
|
if (cfg.picker && sel == SEL_GOIN) {
|
||||||
dents[cur].flags |= FILE_SELECTED;
|
appendfpath(newpath, mkpath(path, dents[cur].name, newpath));
|
||||||
updateselbuf(path, newpath);
|
|
||||||
writesel(pselbuf, selbufpos - 1);
|
writesel(pselbuf, selbufpos - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4640,10 +4621,8 @@ nochange:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg.selmode) {
|
if (cfg.selmode)
|
||||||
updateselbuf(path, newpath);
|
lastappendpos = selbufpos;
|
||||||
ctx_changed = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
savecurctx(&cfg, path, dents[cur].name, r);
|
savecurctx(&cfg, path, dents[cur].name, r);
|
||||||
|
|
||||||
|
@ -4783,11 +4762,7 @@ nochange:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg.selmode) {
|
endselection();
|
||||||
if (nselected)
|
|
||||||
updateselbuf(path, newpath);
|
|
||||||
cfg.selmode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save current */
|
/* Save current */
|
||||||
if (ndents)
|
if (ndents)
|
||||||
|
@ -4821,7 +4796,7 @@ nochange:
|
||||||
refresh = TRUE;
|
refresh = TRUE;
|
||||||
break;
|
break;
|
||||||
case SEL_RENAMEMUL:
|
case SEL_RENAMEMUL:
|
||||||
endselection(path, newpath);
|
endselection();
|
||||||
|
|
||||||
if (!batch_rename(path)) {
|
if (!batch_rename(path)) {
|
||||||
printwait(messages[MSG_FAILED], &presel);
|
printwait(messages[MSG_FAILED], &presel);
|
||||||
|
@ -4849,6 +4824,8 @@ nochange:
|
||||||
if (cfg.filtermode && !refresh)
|
if (cfg.filtermode && !refresh)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
endselection();
|
||||||
|
|
||||||
/* Save current */
|
/* Save current */
|
||||||
if (ndents)
|
if (ndents)
|
||||||
copycurname();
|
copycurname();
|
||||||
|
@ -4869,20 +4846,15 @@ nochange:
|
||||||
|
|
||||||
if (dents[cur].flags & FILE_SELECTED) {
|
if (dents[cur].flags & FILE_SELECTED) {
|
||||||
++nselected;
|
++nselected;
|
||||||
utmp = selbufpos;
|
|
||||||
selbufpos = lastappendpos;
|
|
||||||
appendfpath(newpath, mkpath(path, dents[cur].name, newpath));
|
appendfpath(newpath, mkpath(path, dents[cur].name, newpath));
|
||||||
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
|
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
|
||||||
lastappendpos = selbufpos;
|
|
||||||
selbufpos = utmp;
|
|
||||||
} else {
|
} else {
|
||||||
--nselected;
|
--nselected;
|
||||||
|
selbufpos = lastappendpos;
|
||||||
|
|
||||||
if (nselected) {
|
if (nselected) {
|
||||||
utmp = selbufpos;
|
|
||||||
updateselbuf(path, newpath);
|
updateselbuf(path, newpath);
|
||||||
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
|
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
|
||||||
lastappendpos = selbufpos;
|
|
||||||
selbufpos = utmp;
|
|
||||||
} else
|
} else
|
||||||
writesel(NULL, 0);
|
writesel(NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -4949,9 +4921,6 @@ nochange:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember current selection buffer position */
|
/* Remember current selection buffer position */
|
||||||
utmp = selbufpos;
|
|
||||||
selbufpos = lastappendpos;
|
|
||||||
|
|
||||||
for (r = selstartid; r <= selendid; ++r)
|
for (r = selstartid; r <= selendid; ++r)
|
||||||
if (!(dents[r].flags & FILE_SELECTED)) {
|
if (!(dents[r].flags & FILE_SELECTED)) {
|
||||||
/* Write the path to selection file to avoid flush */
|
/* Write the path to selection file to avoid flush */
|
||||||
|
@ -4961,17 +4930,12 @@ nochange:
|
||||||
++nselected;
|
++nselected;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selbufpos != utmp) {
|
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
|
||||||
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
|
if (cfg.x11)
|
||||||
if (cfg.x11)
|
plugscript(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE);
|
||||||
plugscript(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE);
|
|
||||||
/* Restore current selection buffer position */
|
|
||||||
lastappendpos = selbufpos;
|
|
||||||
selbufpos = utmp;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
case SEL_SELLIST:
|
case SEL_SELLIST:
|
||||||
if (listselbuf(path, newpath) || listselfile()) {
|
if (listselbuf() || listselfile()) {
|
||||||
if (cfg.filtermode)
|
if (cfg.filtermode)
|
||||||
presel = FILTER;
|
presel = FILTER;
|
||||||
break;
|
break;
|
||||||
|
@ -4979,9 +4943,6 @@ nochange:
|
||||||
|
|
||||||
goto nochange;
|
goto nochange;
|
||||||
case SEL_SELEDIT:
|
case SEL_SELEDIT:
|
||||||
if (nselected)
|
|
||||||
updateselbuf(path, newpath);
|
|
||||||
|
|
||||||
r = editselection();
|
r = editselection();
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
const char * msg
|
const char * msg
|
||||||
|
@ -4996,7 +4957,7 @@ nochange:
|
||||||
case SEL_CPMVAS: // fallthrough
|
case SEL_CPMVAS: // fallthrough
|
||||||
case SEL_RMMUL:
|
case SEL_RMMUL:
|
||||||
{
|
{
|
||||||
endselection(path, newpath);
|
endselection();
|
||||||
|
|
||||||
if (!cpmvrm_selection(sel, path, &presel))
|
if (!cpmvrm_selection(sel, path, &presel))
|
||||||
goto nochange;
|
goto nochange;
|
||||||
|
@ -5037,7 +4998,7 @@ nochange:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (sel != SEL_OPENWITH)
|
if (sel != SEL_OPENWITH)
|
||||||
endselection(path, newpath);
|
endselection();
|
||||||
|
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case SEL_ARCHIVE:
|
case SEL_ARCHIVE:
|
||||||
|
@ -5228,7 +5189,7 @@ nochange:
|
||||||
case SEL_PLUGIN: // fallthrough
|
case SEL_PLUGIN: // fallthrough
|
||||||
case SEL_LAUNCH: // fallthrough
|
case SEL_LAUNCH: // fallthrough
|
||||||
case SEL_RUNCMD:
|
case SEL_RUNCMD:
|
||||||
endselection(path, newpath);
|
endselection();
|
||||||
|
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case SEL_EXEC:
|
case SEL_EXEC:
|
||||||
|
|
Loading…
Reference in a new issue