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:
Arun Prakash Jana 2019-12-13 01:57:58 +05:30
parent 5a46b8fb25
commit f73f79d5de
No known key found for this signature in database
GPG key ID: A75979F35C080412

View file

@ -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: