Cleanup of bb->selected (renamed from bb->firstselected) to ensure that
$n arguments for scripts are in FIFO order instead of LIFO order (i.e. $1 is the first selected item). `Ctrl-a` is also now bound to use `+select` instead of `+select: *` which ensures that the correct sorting order is preserved.
This commit is contained in:
parent
8df4cceca0
commit
b9e2bc280b
59
bb.c
59
bb.c
@ -458,7 +458,7 @@ int populate_files(bb_t *bb, const char *path)
|
|||||||
|
|
||||||
size_t space = 0;
|
size_t space = 0;
|
||||||
if (strcmp(bb->path, "<selection>") == 0) {
|
if (strcmp(bb->path, "<selection>") == 0) {
|
||||||
for (entry_t *e = bb->firstselected; e; e = e->selected.next) {
|
for (entry_t *e = bb->selected; e; e = e->selected.next) {
|
||||||
if ((size_t)bb->nfiles + 1 > space)
|
if ((size_t)bb->nfiles + 1 > space)
|
||||||
bb->files = memcheck(realloc(bb->files, (space += 100)*sizeof(void*)));
|
bb->files = memcheck(realloc(bb->files, (space += 100)*sizeof(void*)));
|
||||||
e->index = bb->nfiles;
|
e->index = bb->nfiles;
|
||||||
@ -614,16 +614,15 @@ void run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Filename may no longer exist:
|
// Filename may no longer exist:
|
||||||
for (e = bb->firstselected; e; e = e->selected.next) {
|
for (e = bb->selected; e; e = e->selected.next) {
|
||||||
if (strcmp(e->fullname, pbuf) == 0) {
|
if (strcmp(e->fullname, pbuf) == 0) {
|
||||||
set_selected(bb, e, 0);
|
set_selected(bb, e, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (matches_cmd(cmd, "deselect")) { // +deselect
|
} else if (matches_cmd(cmd, "deselect")) { // +deselect
|
||||||
while (bb->firstselected)
|
while (bb->selected)
|
||||||
set_selected(bb, bb->firstselected, 0);
|
set_selected(bb, bb->selected, 0);
|
||||||
return;
|
|
||||||
} else if (matches_cmd(cmd, "dotfiles:") || matches_cmd(cmd, "dotfiles")) { // +dotfiles:
|
} else if (matches_cmd(cmd, "dotfiles:") || matches_cmd(cmd, "dotfiles")) { // +dotfiles:
|
||||||
set_bool(bb->show_dotfiles);
|
set_bool(bb->show_dotfiles);
|
||||||
setenv("BBDOTFILES", bb->show_dotfiles ? "1" : "", 1);
|
setenv("BBDOTFILES", bb->show_dotfiles ? "1" : "", 1);
|
||||||
@ -720,10 +719,13 @@ void run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
else
|
else
|
||||||
set_scroll(bb, n);
|
set_scroll(bb, n);
|
||||||
} else if (matches_cmd(cmd, "select:") || matches_cmd(cmd, "select")) { // +select:
|
} else if (matches_cmd(cmd, "select:") || matches_cmd(cmd, "select")) { // +select:
|
||||||
if (!value && !bb->nfiles) return;
|
if (!value) {
|
||||||
if (!value) value = bb->files[bb->cursor]->fullname;
|
for (int i = 0; i < bb->nfiles; i++)
|
||||||
entry_t *e = load_entry(bb, value, 1);
|
set_selected(bb, bb->files[i], 1);
|
||||||
if (e) set_selected(bb, e, 1);
|
} else {
|
||||||
|
entry_t *e = load_entry(bb, value, 1);
|
||||||
|
if (e) set_selected(bb, e, 1);
|
||||||
|
}
|
||||||
} else if (matches_cmd(cmd, "sort:")) { // +sort:
|
} else if (matches_cmd(cmd, "sort:")) { // +sort:
|
||||||
set_sort(bb, value);
|
set_sort(bb, value);
|
||||||
sort_files(bb);
|
sort_files(bb);
|
||||||
@ -925,9 +927,9 @@ void render(bb_t *bb)
|
|||||||
move_cursor(tty_out, winsize.ws_col/2, winsize.ws_row - 1);
|
move_cursor(tty_out, winsize.ws_col/2, winsize.ws_row - 1);
|
||||||
fputs("\033[0m\033[K", tty_out);
|
fputs("\033[0m\033[K", tty_out);
|
||||||
int x = winsize.ws_col;
|
int x = winsize.ws_col;
|
||||||
if (bb->firstselected) { // Number of selected files
|
if (bb->selected) { // Number of selected files
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (entry_t *s = bb->firstselected; s; s = s->selected.next) ++n;
|
for (entry_t *s = bb->selected; s; s = s->selected.next) ++n;
|
||||||
x -= 14;
|
x -= 14;
|
||||||
for (int k = n; k; k /= 10) x--;
|
for (int k = n; k; k /= 10) x--;
|
||||||
move_cursor(tty_out, MAX(0, x), winsize.ws_row - 1);
|
move_cursor(tty_out, MAX(0, x), winsize.ws_row - 1);
|
||||||
@ -975,20 +977,18 @@ int run_script(bb_t *bb, const char *cmd)
|
|||||||
fclose(tty_out); tty_out = NULL;
|
fclose(tty_out); tty_out = NULL;
|
||||||
fclose(tty_in); tty_in = NULL;
|
fclose(tty_in); tty_in = NULL;
|
||||||
setpgid(0, 0);
|
setpgid(0, 0);
|
||||||
// TODO: is there a max number of args? Should this be batched?
|
char **args = memcheck(calloc(4 + bb->nselected + 1, sizeof(char*)));
|
||||||
size_t space = 32;
|
int i = 0;
|
||||||
char **args = memcheck(calloc(space, sizeof(char*)));
|
|
||||||
size_t i = 0;
|
|
||||||
args[i++] = SH;
|
args[i++] = SH;
|
||||||
args[i++] = "-c";
|
args[i++] = "-c";
|
||||||
args[i++] = fullcmd;
|
args[i++] = fullcmd;
|
||||||
args[i++] = "--"; // ensure files like "-i" are not interpreted as flags for sh
|
args[i++] = "--"; // ensure files like "-i" are not interpreted as flags for sh
|
||||||
for (entry_t *e = bb->firstselected; e; e = e->selected.next) {
|
// bb->selected is in most-recent order, so populate args in reverse to make sure
|
||||||
if (i >= space)
|
// that $1 is the first selected, etc.
|
||||||
args = memcheck(realloc(args, (space += 100)*sizeof(char*)));
|
i += bb->nselected;
|
||||||
args[i++] = e->fullname;
|
for (entry_t *e = bb->selected; e; e = e->selected.next)
|
||||||
}
|
args[--i] = e->fullname;
|
||||||
args[i] = NULL;
|
|
||||||
setenv("BBCURSOR", bb->nfiles ? bb->files[bb->cursor]->fullname : "", 1);
|
setenv("BBCURSOR", bb->nfiles ? bb->files[bb->cursor]->fullname : "", 1);
|
||||||
|
|
||||||
int ttyout, ttyin;
|
int ttyout, ttyin;
|
||||||
@ -1072,10 +1072,12 @@ void set_selected(bb_t *bb, entry_t *e, int selected)
|
|||||||
dirty = 1;
|
dirty = 1;
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
LL_PREPEND(bb->firstselected, e, selected);
|
LL_PREPEND(bb->selected, e, selected);
|
||||||
|
++bb->nselected;
|
||||||
} else {
|
} else {
|
||||||
LL_REMOVE(e, selected);
|
LL_REMOVE(e, selected);
|
||||||
try_free_entry(e);
|
try_free_entry(e);
|
||||||
|
--bb->nselected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,8 +1303,8 @@ int main(int argc, char *argv[])
|
|||||||
fputs(T_LEAVE_BBMODE, tty_out);
|
fputs(T_LEAVE_BBMODE, tty_out);
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
if (bb->firstselected && print_selection) {
|
if (bb->selected && print_selection) {
|
||||||
for (entry_t *e = bb->firstselected; e; e = e->selected.next) {
|
for (entry_t *e = bb->selected; e; e = e->selected.next) {
|
||||||
write(STDOUT_FILENO, e->fullname, strlen(e->fullname));
|
write(STDOUT_FILENO, e->fullname, strlen(e->fullname));
|
||||||
write(STDOUT_FILENO, &sep, 1);
|
write(STDOUT_FILENO, &sep, 1);
|
||||||
}
|
}
|
||||||
@ -1313,13 +1315,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Cleanup:
|
// Cleanup:
|
||||||
populate_files(bb, NULL);
|
populate_files(bb, NULL);
|
||||||
for (entry_t *next, *e = bb->firstselected; e; e = next) {
|
while (bb->selected)
|
||||||
next = e->selected.next;
|
set_selected(bb, bb->selected, 0);
|
||||||
e->selected.atme = NULL;
|
|
||||||
e->selected.next = NULL;
|
|
||||||
try_free_entry(e);
|
|
||||||
}
|
|
||||||
bb->firstselected = NULL;
|
|
||||||
free(bb);
|
free(bb);
|
||||||
if (cmdfilename) free(cmdfilename);
|
if (cmdfilename) free(cmdfilename);
|
||||||
|
|
||||||
|
6
bb.h
6
bb.h
@ -25,7 +25,7 @@
|
|||||||
#include "bterm.h"
|
#include "bterm.h"
|
||||||
|
|
||||||
// Macros:
|
// Macros:
|
||||||
#define BB_VERSION "0.19.0"
|
#define BB_VERSION "0.19.1"
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
#define PATH_MAX 4096
|
#define PATH_MAX 4096
|
||||||
@ -136,10 +136,10 @@ typedef struct entry_s {
|
|||||||
typedef struct bb_s {
|
typedef struct bb_s {
|
||||||
entry_t *hash[HASH_SIZE];
|
entry_t *hash[HASH_SIZE];
|
||||||
entry_t **files;
|
entry_t **files;
|
||||||
entry_t *firstselected;
|
entry_t *selected;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
char prev_path[PATH_MAX];
|
char prev_path[PATH_MAX];
|
||||||
int nfiles;
|
int nfiles, nselected;
|
||||||
int scroll, cursor;
|
int scroll, cursor;
|
||||||
|
|
||||||
char sort[MAX_SORT+1];
|
char sort[MAX_SORT+1];
|
||||||
|
@ -81,8 +81,7 @@ Shift-Home: # Spread the selection to the top
|
|||||||
Shift-End: # Spread the selection to the bottom
|
Shift-End: # Spread the selection to the bottom
|
||||||
bb +spread:100%n
|
bb +spread:100%n
|
||||||
Ctrl-a: # Select all files here
|
Ctrl-a: # Select all files here
|
||||||
if [ $BBDOTFILES ]; then bb +sel: * .[!.]* ..?*
|
bb +select
|
||||||
else bb +sel: *; fi
|
|
||||||
|
|
||||||
Section: File Actions
|
Section: File Actions
|
||||||
Left click: # Move cursor to file
|
Left click: # Move cursor to file
|
||||||
|
Loading…
Reference in New Issue
Block a user