Added flags for toggling columns, cleaned up a bit

This commit is contained in:
Bruce Hill 2019-05-23 05:42:33 -07:00
parent 670ee76177
commit 2862756733

317
bb.c
View File

@ -36,6 +36,7 @@ static int termfd;
static int width, height;
static int mouse_x, mouse_y;
static int force_redraw = 0;
static int display_permissions = 1, display_times = 1, display_sizes = 1;
typedef enum {
SORT_ALPHA = 0,
@ -243,19 +244,29 @@ static void render(bb_state_t *state, int lazy)
if (!lazy) {
term_move(0,0);
writez(termfd, "\e[0;1m"); // reset color + bold
write_escaped(termfd, state->path, strlen(state->path), "\e[0;1m");
writez(termfd, "\e[0;1;30;47m ");
write_escaped(termfd, state->path, strlen(state->path), "\e[0;1;30;47m");
writez(termfd, "\e[K\e[0m");
term_move(0,1);
{ // Column labels
char buf[] = " \e[42;30m Size | Date | Perm| Name \e[0m";
buf[11] = state->sortmethod == SORT_SIZE ? (state->sort_reverse ? '-' : '+') : ' ';
buf[24] = state->sortmethod == SORT_TIME ? (state->sort_reverse ? '-' : '+') : ' ';
buf[39] = state->sortmethod == SORT_PERM ? (state->sort_reverse ? '-' : '+') : ' ';
buf[45] = state->sortmethod == SORT_ALPHA ? (state->sort_reverse ? '-' : '+') : ' ';
writez(termfd, buf);
writez(termfd, "\e[K");
writez(termfd, "\e[44;30m ");
if (display_sizes) {
writez(termfd, " ");
writez(termfd, state->sortmethod == SORT_SIZE ? (state->sort_reverse ? "" : "") : " ");
writez(termfd, "Size |");
}
if (display_times) {
writez(termfd, " ");
writez(termfd, state->sortmethod == SORT_TIME ? (state->sort_reverse ? "" : "") : " ");
writez(termfd, "Date |");
}
if (display_permissions) {
writez(termfd, state->sortmethod == SORT_PERM ? (state->sort_reverse ? "" : "") : " ");
writez(termfd, "Perm|");
}
writez(termfd, state->sortmethod == SORT_ALPHA ? (state->sort_reverse ? "" : "") : " ");
writez(termfd, "Name\e[K\e[0m");
}
}
@ -271,7 +282,7 @@ static void render(bb_state_t *state, int lazy)
entry_t **files = state->files;
static const char *NORMAL_COLOR = "\e[0m";
static const char *CURSOR_COLOR = "\e[0;30;47m";
static const char *CURSOR_COLOR = "\e[0;30;43m";
static const char *LINKDIR_COLOR = "\e[0;36m";
static const char *DIR_COLOR = "\e[0;34m";
static const char *LINK_COLOR = "\e[0;33m";
@ -316,7 +327,7 @@ static void render(bb_state_t *state, int lazy)
color = NORMAL_COLOR;
writez(termfd, color);
{ // Filesize:
if (display_sizes) {
int j = 0;
const char* units = "BKMGTPEZY";
double bytes = (double)info.st_size;
@ -329,7 +340,7 @@ static void render(bb_state_t *state, int lazy)
writez(termfd, buf);
}
{ // Date:
if (display_times) {
char buf[64];
strftime(buf, sizeof(buf), "%l:%M%p %b %e %Y", localtime(&(info.st_mtime)));
writez(termfd, buf);
@ -337,7 +348,7 @@ static void render(bb_state_t *state, int lazy)
writez(termfd, "");
}
{ // Permissions:
if (display_permissions) { // Permissions:
char buf[] = {
'0' + ((info.st_mode >> 6) & 7),
'0' + ((info.st_mode >> 3) & 7),
@ -357,7 +368,7 @@ static void render(bb_state_t *state, int lazy)
ssize_t pathlen;
if ((pathlen = readlink(entry->d_name, linkpath, sizeof(linkpath))) < 0)
err("readlink() failed");
writez(termfd, " -> ");
writez(termfd, "\e[2m -> ");
write_escaped(termfd, linkpath, pathlen, color);
if (entry->d_isdir)
writez(termfd, "/");
@ -779,142 +790,143 @@ static void explore(char *path, int print_dir, int print_selection, char sep)
// Scan for IPC requests
int needs_full_refresh = 0;
FILE *tmpfile;
if ((tmpfile = fopen(bb_tmpfile, "r"))) {
char *line = NULL;
size_t capacity = 0;
ssize_t len;
while ((len = getline(&line, &capacity, tmpfile)) >= 0) {
if (len > 0 && line[len-1] == '\n') line[--len] = '\0';
char *value = strchr(line, ':');
if (value) ++value;
if (strcmp(line, "refresh") == 0) {
needs_full_refresh = 1;
} else if (strcmp(line, "quit") == 0) {
goto done;
} else if (startswith(line, "sort:")) {
sortmethod_t oldsort = state.sortmethod;
switch (value[0]) {
case '\0': continue;
case 'a': state.sortmethod = SORT_ALPHA; break;
case 's': state.sortmethod = SORT_SIZE; break;
case 't': state.sortmethod = SORT_TIME; break;
case 'p': state.sortmethod = SORT_PERM; break;
default: break;
}
if (value[1] == '+')
state.sort_reverse = 0;
else if (value[1] == '-')
state.sort_reverse = 1;
else if (state.sortmethod == oldsort)
state.sort_reverse ^= 1;
strcpy(to_select, state.files[state.cursor]->d_name);
goto sort_files;
} else if (startswith(line, "cd:")) {
free(path);
path = calloc(strlen(line+strlen("cd:")) + 1, sizeof(char));
strcpy(path, line+strlen("cd:"));
goto tail_call;
} else if (startswith(line, "toggle:")) {
lazy = 0;
entry_t *e = find_file(&state, line + strlen("select:"));
if (e) {
if (IS_SELECTED(e)) deselect_file(&state, e);
else select_file(&state, e);
}
} else if (startswith(line, "select:")) {
lazy = 0;
if (strcmp(value, "*") == 0) {
for (int i = 0; i < state.nfiles; i++)
select_file(&state, state.files[i]);
} else {
entry_t *e = find_file(&state, value);
if (e) select_file(&state, e);
}
} else if (startswith(line, "deselect:")) {
lazy = 0;
if (strcmp(value, "*") == 0) {
clear_selection(&state);
} else {
entry_t *e = find_file(&state, value);
if (e) select_file(&state, e);
}
} else if (startswith(line, "cursor:")) {
for (int i = 0; i < state.nfiles; i++) {
if (strcmp(value[0] == '/' ?
state.files[i]->d_fullname : state.files[i]->d_name,
value) == 0) {
state.cursor = i;
goto found_it;
}
}
free(path);
char *lastslash = strrchr(value, '/');
if (!lastslash) goto found_it;
size_t len = lastslash - value;
path = calloc(len + 1, sizeof(char));
memcpy(path, value, len);
strcpy(to_select, lastslash+1);
goto tail_call;
found_it:;
} else if (startswith(line, "move:")) {
int expand_sel = 0;
if (*value == 'x') {
expand_sel = 1;
++value;
}
int oldcur = state.cursor;
int isabs = value[0] != '-' && value[0] != '+';
long delta = strtol(value, &value, 10);
if (*value == '%') delta = (delta * height)/100;
if (isabs) state.cursor = delta;
else state.cursor += delta;
if (!(tmpfile = fopen(bb_tmpfile, "r")))
goto redraw;
state.cursor = clamped(state.cursor, 0, state.nfiles-1);
delta = state.cursor - oldcur;
if (state.nfiles > height-4) {
if (delta > 0) {
if (state.cursor >= state.scroll + (height-4) - scrolloff)
state.scroll += delta;
} else if (delta < 0) {
if (state.cursor <= state.scroll + scrolloff)
state.scroll += delta;
}
//int target = clamped(state.scroll, state.cursor - (height-4) + scrolloff, state.cursor - scrolloff);
//state.scroll += (delta > 0 ? 1 : -1)*MIN(abs(target-state.scroll), abs((int)delta));
//state.scroll = target;
state.scroll = clamped(state.scroll, state.cursor - (height-4) + 1, state.cursor);
state.scroll = clamped(state.scroll, 0, state.nfiles-1 - (height-4));
}
if (expand_sel) {
int sel = IS_SELECTED(state.files[oldcur]);
for (int i = state.cursor; i != oldcur; i += (oldcur > i ? 1 : -1)) {
if (sel && !IS_SELECTED(state.files[i]))
select_file(&state, state.files[i]);
else if (!sel && IS_SELECTED(state.files[i]))
deselect_file(&state, state.files[i]);
}
lazy &= abs(oldcur - state.cursor) <= 1;
}
} else if (startswith(line, "scroll:")) {
int oldscroll = state.scroll;
int isabs = value[0] != '-' && value[0] != '+';
long delta = strtol(value, &value, 10);
if (*value == '%') delta = (delta * height)/100;
if (state.nfiles > height-4) {
if (isabs) state.scroll = delta;
else state.scroll += delta;
state.scroll = clamped(state.scroll, 0, state.nfiles-1 - (height-4));
}
state.cursor = clamped(state.cursor + delta, 0, state.nfiles-1);
char *line = NULL;
size_t capacity = 0;
ssize_t len;
while ((len = getline(&line, &capacity, tmpfile)) >= 0) {
if (len > 0 && line[len-1] == '\n') line[--len] = '\0';
char *value = strchr(line, ':');
if (value) ++value;
if (strcmp(line, "refresh") == 0) {
needs_full_refresh = 1;
} else if (strcmp(line, "quit") == 0) {
goto done;
} else if (startswith(line, "sort:")) {
sortmethod_t oldsort = state.sortmethod;
switch (value[0]) {
case '\0': continue;
case 'a': state.sortmethod = SORT_ALPHA; break;
case 's': state.sortmethod = SORT_SIZE; break;
case 't': state.sortmethod = SORT_TIME; break;
case 'p': state.sortmethod = SORT_PERM; break;
default: break;
}
if (value[1] == '+')
state.sort_reverse = 0;
else if (value[1] == '-')
state.sort_reverse = 1;
else if (state.sortmethod == oldsort)
state.sort_reverse ^= 1;
strcpy(to_select, state.files[state.cursor]->d_name);
goto sort_files;
} else if (startswith(line, "cd:")) {
free(path);
path = calloc(strlen(line+strlen("cd:")) + 1, sizeof(char));
strcpy(path, line+strlen("cd:"));
goto tail_call;
} else if (startswith(line, "toggle:")) {
lazy = 0;
entry_t *e = find_file(&state, line + strlen("select:"));
if (e) {
if (IS_SELECTED(e)) deselect_file(&state, e);
else select_file(&state, e);
}
} else if (startswith(line, "select:")) {
lazy = 0;
if (strcmp(value, "*") == 0) {
for (int i = 0; i < state.nfiles; i++)
select_file(&state, state.files[i]);
} else {
entry_t *e = find_file(&state, value);
if (e) select_file(&state, e);
}
} else if (startswith(line, "deselect:")) {
lazy = 0;
if (strcmp(value, "*") == 0) {
clear_selection(&state);
} else {
entry_t *e = find_file(&state, value);
if (e) select_file(&state, e);
}
} else if (startswith(line, "cursor:")) {
for (int i = 0; i < state.nfiles; i++) {
if (strcmp(value[0] == '/' ?
state.files[i]->d_fullname : state.files[i]->d_name,
value) == 0) {
state.cursor = i;
goto found_it;
}
}
free(path);
char *lastslash = strrchr(value, '/');
if (!lastslash) goto found_it;
size_t len = lastslash - value;
path = calloc(len + 1, sizeof(char));
memcpy(path, value, len);
strcpy(to_select, lastslash+1);
goto tail_call;
found_it:;
} else if (startswith(line, "move:")) {
int expand_sel = 0;
if (*value == 'x') {
expand_sel = 1;
++value;
}
int oldcur = state.cursor;
int isabs = value[0] != '-' && value[0] != '+';
long delta = strtol(value, &value, 10);
if (*value == '%') delta = (delta * height)/100;
if (isabs) state.cursor = delta;
else state.cursor += delta;
state.cursor = clamped(state.cursor, 0, state.nfiles-1);
delta = state.cursor - oldcur;
if (state.nfiles > height-4) {
if (delta > 0) {
if (state.cursor >= state.scroll + (height-4) - scrolloff)
state.scroll += delta;
} else if (delta < 0) {
if (state.cursor <= state.scroll + scrolloff)
state.scroll += delta;
}
//int target = clamped(state.scroll, state.cursor - (height-4) + scrolloff, state.cursor - scrolloff);
//state.scroll += (delta > 0 ? 1 : -1)*MIN(abs(target-state.scroll), abs((int)delta));
//state.scroll = target;
state.scroll = clamped(state.scroll, state.cursor - (height-4) + 1, state.cursor);
state.scroll = clamped(state.scroll, 0, state.nfiles-1 - (height-4));
}
if (expand_sel) {
int sel = IS_SELECTED(state.files[oldcur]);
for (int i = state.cursor; i != oldcur; i += (oldcur > i ? 1 : -1)) {
if (sel && !IS_SELECTED(state.files[i]))
select_file(&state, state.files[i]);
else if (!sel && IS_SELECTED(state.files[i]))
deselect_file(&state, state.files[i]);
}
lazy &= abs(oldcur - state.cursor) <= 1;
}
} else if (startswith(line, "scroll:")) {
int oldscroll = state.scroll;
int isabs = value[0] != '-' && value[0] != '+';
long delta = strtol(value, &value, 10);
if (*value == '%') delta = (delta * height)/100;
if (state.nfiles > height-4) {
if (isabs) state.scroll = delta;
else state.scroll += delta;
state.scroll = clamped(state.scroll, 0, state.nfiles-1 - (height-4));
}
state.cursor = clamped(state.cursor + delta, 0, state.nfiles-1);
}
if (line) free(line);
fclose(tmpfile);
unlink(bb_tmpfile);
}
if (line) free(line);
fclose(tmpfile);
unlink(bb_tmpfile);
if (needs_full_refresh) {
strcpy(to_select, state.files[state.cursor]->d_name);
@ -994,8 +1006,10 @@ int main(int argc, char *argv[])
fclose(f);
return 0;
}
if (argv[i][0] == '-' && argv[i][1] == '-')
if (argv[i][0] == '-' && argv[i][1] == '-') {
if (argv[i][2] == '\0') break;
continue;
}
if (argv[i][0] == '-') {
for (char *c = &argv[i][1]; *c; c++) {
switch (*c) {
@ -1017,6 +1031,15 @@ int main(int argc, char *argv[])
print_bindings(1);
exit(0);
break;
case 'P':
display_permissions = 0;
break;
case 'T':
display_times = 0;
break;
case 'S':
display_sizes = 0;
break;
}
}
continue;