Converted block comments to line comments
This commit is contained in:
parent
8842891a7c
commit
000ef2dc58
243
bb.c
243
bb.c
@ -1,10 +1,10 @@
|
|||||||
/*
|
//
|
||||||
* Bitty Browser (bb)
|
// Bitty Browser (bb)
|
||||||
* Copyright 2019 Bruce Hill
|
// Copyright 2019 Bruce Hill
|
||||||
* Released under the MIT license
|
// Released under the MIT license
|
||||||
*
|
//
|
||||||
* This file contains the main source code of `bb`.
|
// This file contains the main source code of `bb`.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -107,9 +107,9 @@ static struct winsize winsize = {0};
|
|||||||
static char cmdfilename[PATH_MAX] = {0};
|
static char cmdfilename[PATH_MAX] = {0};
|
||||||
static bb_t *current_bb = NULL;
|
static bb_t *current_bb = NULL;
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Use bb to browse the filesystem.
|
// Use bb to browse the filesystem.
|
||||||
*/
|
//
|
||||||
void bb_browse(bb_t *bb, const char *initial_path)
|
void bb_browse(bb_t *bb, const char *initial_path)
|
||||||
{
|
{
|
||||||
if (populate_files(bb, initial_path))
|
if (populate_files(bb, initial_path))
|
||||||
@ -123,10 +123,10 @@ void bb_browse(bb_t *bb, const char *initial_path)
|
|||||||
run_script(bb, "bbshutdown");
|
run_script(bb, "bbshutdown");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Check the bb command file and run any and all commands that have been
|
// Check the bb command file and run any and all commands that have been
|
||||||
* written to it.
|
// written to it.
|
||||||
*/
|
//
|
||||||
static void check_cmdfile(bb_t *bb)
|
static void check_cmdfile(bb_t *bb)
|
||||||
{
|
{
|
||||||
FILE *cmdfile = fopen(cmdfilename, "r");
|
FILE *cmdfile = fopen(cmdfilename, "r");
|
||||||
@ -143,9 +143,9 @@ static void check_cmdfile(bb_t *bb)
|
|||||||
unlink(cmdfilename);
|
unlink(cmdfilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Clean up the terminal before going to the default signal handling behavior.
|
// Clean up the terminal before going to the default signal handling behavior.
|
||||||
*/
|
//
|
||||||
static void cleanup_and_raise(int sig)
|
static void cleanup_and_raise(int sig)
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
@ -163,9 +163,9 @@ static void cleanup_and_raise(int sig)
|
|||||||
sigaction(sig, &sa, NULL);
|
sigaction(sig, &sa, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Reset the screen and delete the cmdfile
|
// Reset the screen and delete the cmdfile
|
||||||
*/
|
//
|
||||||
static void cleanup(void)
|
static void cleanup(void)
|
||||||
{
|
{
|
||||||
if (cmdfilename[0]) {
|
if (cmdfilename[0]) {
|
||||||
@ -179,10 +179,10 @@ static void cleanup(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Used for sorting, this function compares files according to the sorting-related options,
|
// Used for sorting, this function compares files according to the sorting-related options,
|
||||||
* like bb->sort
|
// like bb->sort
|
||||||
*/
|
//
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static int compare_files(void *v, const void *v1, const void *v2)
|
static int compare_files(void *v, const void *v1, const void *v2)
|
||||||
#else
|
#else
|
||||||
@ -204,14 +204,13 @@ static int compare_files(const void *v1, const void *v2, void *v)
|
|||||||
switch (*sort) {
|
switch (*sort) {
|
||||||
case COL_SELECTED: COMPARE(IS_SELECTED(e1), IS_SELECTED(e2)); break;
|
case COL_SELECTED: COMPARE(IS_SELECTED(e1), IS_SELECTED(e2)); break;
|
||||||
case COL_NAME: {
|
case COL_NAME: {
|
||||||
/* This sorting method is not identical to strverscmp(). Notably, bb's sort
|
// This sorting method is not identical to strverscmp(). Notably, bb's sort
|
||||||
* will order: [0, 1, 9, 00, 01, 09, 10, 000, 010] instead of strverscmp()'s
|
// will order: [0, 1, 9, 00, 01, 09, 10, 000, 010] instead of strverscmp()'s
|
||||||
* order: [000, 00, 01, 010, 09, 0, 1, 9, 10]. I believe bb's sort is consistent
|
// order: [000, 00, 01, 010, 09, 0, 1, 9, 10]. I believe bb's sort is consistent
|
||||||
* with how people want their files grouped: all files padded to n digits
|
// with how people want their files grouped: all files padded to n digits
|
||||||
* will be grouped together, and files with the same padding will be sorted
|
// will be grouped together, and files with the same padding will be sorted
|
||||||
* ordinally. This version also does case-insensitivity by lowercasing words,
|
// ordinally. This version also does case-insensitivity by lowercasing words,
|
||||||
* so the following characters come before all letters: [\]^_`
|
// so the following characters come before all letters: [\]^_`
|
||||||
*/
|
|
||||||
const char *n1 = e1->name, *n2 = e2->name;
|
const char *n1 = e1->name, *n2 = e2->name;
|
||||||
while (*n1 && *n2) {
|
while (*n1 && *n2) {
|
||||||
char c1 = tolower(*n1), c2 = tolower(*n2);
|
char c1 = tolower(*n1), c2 = tolower(*n2);
|
||||||
@ -246,10 +245,10 @@ static int compare_files(const void *v1, const void *v2, void *v)
|
|||||||
#undef COMPARE_TIME
|
#undef COMPARE_TIME
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Wait until the user has pressed a key with an associated key binding and run
|
// Wait until the user has pressed a key with an associated key binding and run
|
||||||
* that binding.
|
// that binding.
|
||||||
*/
|
//
|
||||||
static void handle_next_key_binding(bb_t *bb)
|
static void handle_next_key_binding(bb_t *bb)
|
||||||
{
|
{
|
||||||
int key, mouse_x, mouse_y;
|
int key, mouse_x, mouse_y;
|
||||||
@ -309,10 +308,10 @@ static void handle_next_key_binding(bb_t *bb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Initialize the terminal files for /dev/tty and set up some desired
|
// Initialize the terminal files for /dev/tty and set up some desired
|
||||||
* attributes like passing Ctrl-c as a key instead of interrupting
|
// attributes like passing Ctrl-c as a key instead of interrupting
|
||||||
*/
|
//
|
||||||
static void init_term(void)
|
static void init_term(void)
|
||||||
{
|
{
|
||||||
if (tcsetattr(fileno(tty_out), TCSANOW, &bb_termios) == -1)
|
if (tcsetattr(fileno(tty_out), TCSANOW, &bb_termios) == -1)
|
||||||
@ -323,10 +322,10 @@ static void init_term(void)
|
|||||||
fflush(tty_out);
|
fflush(tty_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Return whether or not 's' is a simple bb command that doesn't need
|
// Return whether or not 's' is a simple bb command that doesn't need
|
||||||
* a full shell instance (e.g. "bbcmd cd:.." or "bbcmd move:+1").
|
// a full shell instance (e.g. "bbcmd cd:.." or "bbcmd move:+1").
|
||||||
*/
|
//
|
||||||
static int is_simple_bbcmd(const char *s)
|
static int is_simple_bbcmd(const char *s)
|
||||||
{
|
{
|
||||||
if (!s) return 0;
|
if (!s) return 0;
|
||||||
@ -341,12 +340,12 @@ static int is_simple_bbcmd(const char *s)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Load a file's info into an entry_t and return it (if found).
|
// Load a file's info into an entry_t and return it (if found).
|
||||||
* The returned entry must be free()ed by the caller.
|
// The returned entry must be free()ed by the caller.
|
||||||
* Warning: this does not deduplicate entries, and it's best if there aren't
|
// Warning: this does not deduplicate entries, and it's best if there aren't
|
||||||
* duplicate entries hanging around.
|
// duplicate entries hanging around.
|
||||||
*/
|
//
|
||||||
static entry_t* load_entry(bb_t *bb, const char *path)
|
static entry_t* load_entry(bb_t *bb, const char *path)
|
||||||
{
|
{
|
||||||
struct stat linkedstat, filestat;
|
struct stat linkedstat, filestat;
|
||||||
@ -397,10 +396,10 @@ static entry_t* load_entry(bb_t *bb, const char *path)
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Return whether a string matches a command
|
// Return whether a string matches a command
|
||||||
* e.g. matches_cmd("sel:x", "select:") == 1, matches_cmd("q", "quit") == 1
|
// e.g. matches_cmd("sel:x", "select:") == 1, matches_cmd("q", "quit") == 1
|
||||||
*/
|
//
|
||||||
static inline int matches_cmd(const char *str, const char *cmd)
|
static inline int matches_cmd(const char *str, const char *cmd)
|
||||||
{
|
{
|
||||||
if ((strchr(cmd, ':') == NULL) != (strchr(str, ':') == NULL))
|
if ((strchr(cmd, ':') == NULL) != (strchr(str, ':') == NULL))
|
||||||
@ -409,20 +408,20 @@ static inline int matches_cmd(const char *str, const char *cmd)
|
|||||||
return *str == '\0' || *str == ':';
|
return *str == '\0' || *str == ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Memory allocation failures are unrecoverable in bb, so this wrapper just
|
// Memory allocation failures are unrecoverable in bb, so this wrapper just
|
||||||
* prints an error message and exits if that happens.
|
// prints an error message and exits if that happens.
|
||||||
*/
|
//
|
||||||
static void* memcheck(void *p)
|
static void* memcheck(void *p)
|
||||||
{
|
{
|
||||||
if (!p) err("Allocation failure");
|
if (!p) err("Allocation failure");
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Prepend `root` to relative paths, replace "~" with $HOME.
|
// Prepend `root` to relative paths, replace "~" with $HOME.
|
||||||
* The normalized path is stored in `normalized`.
|
// The normalized path is stored in `normalized`.
|
||||||
*/
|
//
|
||||||
static char *normalize_path(const char *root, const char *path, char *normalized)
|
static char *normalize_path(const char *root, const char *path, char *normalized)
|
||||||
{
|
{
|
||||||
char pbuf[PATH_MAX] = {0};
|
char pbuf[PATH_MAX] = {0};
|
||||||
@ -443,10 +442,10 @@ static char *normalize_path(const char *root, const char *path, char *normalized
|
|||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Remove all the files currently stored in bb->files and if `bb->path` is
|
// Remove all the files currently stored in bb->files and if `bb->path` is
|
||||||
* non-NULL, update `bb` with a listing of the files in `path`
|
// non-NULL, update `bb` with a listing of the files in `path`
|
||||||
*/
|
//
|
||||||
static int populate_files(bb_t *bb, const char *path)
|
static int populate_files(bb_t *bb, const char *path)
|
||||||
{
|
{
|
||||||
int samedir = path && strcmp(bb->path, path) == 0;
|
int samedir = path && strcmp(bb->path, path) == 0;
|
||||||
@ -558,9 +557,9 @@ static int populate_files(bb_t *bb, const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Print the current key bindings
|
// Print the current key bindings
|
||||||
*/
|
//
|
||||||
static void print_bindings(int fd)
|
static void print_bindings(int fd)
|
||||||
{
|
{
|
||||||
char buf[1000], buf2[1024];
|
char buf[1000], buf2[1024];
|
||||||
@ -591,10 +590,10 @@ static void print_bindings(int fd)
|
|||||||
write(fd, "\n", 1);
|
write(fd, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Run a bb internal command (e.g. "+refresh") and return an indicator of what
|
// Run a bb internal command (e.g. "+refresh") and return an indicator of what
|
||||||
* needs to happen next.
|
// needs to happen next.
|
||||||
*/
|
//
|
||||||
static void run_bbcmd(bb_t *bb, const char *cmd)
|
static void run_bbcmd(bb_t *bb, const char *cmd)
|
||||||
{
|
{
|
||||||
while (*cmd == ' ' || *cmd == '\n') ++cmd;
|
while (*cmd == ' ' || *cmd == '\n') ++cmd;
|
||||||
@ -788,9 +787,9 @@ static void run_bbcmd(bb_t *bb, const char *cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Close the /dev/tty terminals and restore some of the attributes.
|
// Close the /dev/tty terminals and restore some of the attributes.
|
||||||
*/
|
//
|
||||||
static void restore_term(const struct termios *term)
|
static void restore_term(const struct termios *term)
|
||||||
{
|
{
|
||||||
tcsetattr(fileno(tty_out), TCSANOW, term);
|
tcsetattr(fileno(tty_out), TCSANOW, term);
|
||||||
@ -798,11 +797,11 @@ static void restore_term(const struct termios *term)
|
|||||||
fflush(tty_out);
|
fflush(tty_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Run a shell script with the selected files passed as sequential arguments to
|
// Run a shell script with the selected files passed as sequential arguments to
|
||||||
* the script (or pass the cursor file if none are selected).
|
// the script (or pass the cursor file if none are selected).
|
||||||
* Return the exit status of the script.
|
// Return the exit status of the script.
|
||||||
*/
|
//
|
||||||
static int run_script(bb_t *bb, const char *cmd)
|
static int run_script(bb_t *bb, const char *cmd)
|
||||||
{
|
{
|
||||||
proc_t *proc = memcheck(calloc(1, sizeof(proc_t)));
|
proc_t *proc = memcheck(calloc(1, sizeof(proc_t)));
|
||||||
@ -843,18 +842,18 @@ static int run_script(bb_t *bb, const char *cmd)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Set the columns displayed by bb.
|
// Set the columns displayed by bb.
|
||||||
*/
|
//
|
||||||
static void set_columns(bb_t *bb, const char *cols)
|
static void set_columns(bb_t *bb, const char *cols)
|
||||||
{
|
{
|
||||||
strncpy(bb->columns, cols, MAX_COLS);
|
strncpy(bb->columns, cols, MAX_COLS);
|
||||||
setenv("BBCOLUMNS", bb->columns, 1);
|
setenv("BBCOLUMNS", bb->columns, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Set bb's file cursor to the given index (and adjust the scroll as necessary)
|
// Set bb's file cursor to the given index (and adjust the scroll as necessary)
|
||||||
*/
|
//
|
||||||
static void set_cursor(bb_t *bb, int newcur)
|
static void set_cursor(bb_t *bb, int newcur)
|
||||||
{
|
{
|
||||||
int oldcur = bb->cursor;
|
int oldcur = bb->cursor;
|
||||||
@ -881,9 +880,9 @@ static void set_cursor(bb_t *bb, int newcur)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Set the glob pattern(s) used by bb. Patterns are ' ' delimited
|
// Set the glob pattern(s) used by bb. Patterns are ' ' delimited
|
||||||
*/
|
//
|
||||||
static void set_globs(bb_t *bb, const char *globs)
|
static void set_globs(bb_t *bb, const char *globs)
|
||||||
{
|
{
|
||||||
free(bb->globpats);
|
free(bb->globpats);
|
||||||
@ -892,9 +891,9 @@ static void set_globs(bb_t *bb, const char *globs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Set whether or not bb should interleave directories and files.
|
// Set whether or not bb should interleave directories and files.
|
||||||
*/
|
//
|
||||||
static void set_interleave(bb_t *bb, int interleave)
|
static void set_interleave(bb_t *bb, int interleave)
|
||||||
{
|
{
|
||||||
bb->interleave_dirs = interleave;
|
bb->interleave_dirs = interleave;
|
||||||
@ -903,9 +902,9 @@ static void set_interleave(bb_t *bb, int interleave)
|
|||||||
bb->dirty = 1;
|
bb->dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Set bb's scroll to the given index (and adjust the cursor as necessary)
|
// Set bb's scroll to the given index (and adjust the cursor as necessary)
|
||||||
*/
|
//
|
||||||
static void set_scroll(bb_t *bb, int newscroll)
|
static void set_scroll(bb_t *bb, int newscroll)
|
||||||
{
|
{
|
||||||
int delta = newscroll - bb->scroll;
|
int delta = newscroll - bb->scroll;
|
||||||
@ -923,9 +922,9 @@ static void set_scroll(bb_t *bb, int newscroll)
|
|||||||
if (bb->cursor < 0) bb->cursor = 0;
|
if (bb->cursor < 0) bb->cursor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Select or deselect a file.
|
// Select or deselect a file.
|
||||||
*/
|
//
|
||||||
static void set_selected(bb_t *bb, entry_t *e, int selected)
|
static void set_selected(bb_t *bb, entry_t *e, int selected)
|
||||||
{
|
{
|
||||||
if (IS_SELECTED(e) == selected) return;
|
if (IS_SELECTED(e) == selected) return;
|
||||||
@ -943,9 +942,9 @@ static void set_selected(bb_t *bb, entry_t *e, int selected)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Set the sorting method used by bb to display files.
|
// Set the sorting method used by bb to display files.
|
||||||
*/
|
//
|
||||||
static void set_sort(bb_t *bb, const char *sort)
|
static void set_sort(bb_t *bb, const char *sort)
|
||||||
{
|
{
|
||||||
char sortbuf[strlen(sort)+1];
|
char sortbuf[strlen(sort)+1];
|
||||||
@ -965,9 +964,9 @@ static void set_sort(bb_t *bb, const char *sort)
|
|||||||
setenv("BBSORT", bb->sort, 1);
|
setenv("BBSORT", bb->sort, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Set the xwindow title property to: bb - current path
|
// Set the xwindow title property to: bb - current path
|
||||||
*/
|
//
|
||||||
static void set_title(bb_t *bb)
|
static void set_title(bb_t *bb)
|
||||||
{
|
{
|
||||||
char *home = getenv("HOME");
|
char *home = getenv("HOME");
|
||||||
@ -977,10 +976,10 @@ static void set_title(bb_t *bb)
|
|||||||
fprintf(tty_out, "\033]2;"BB_NAME": %s\007", bb->path);
|
fprintf(tty_out, "\033]2;"BB_NAME": %s\007", bb->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* If the given entry is not viewed or selected, remove it from the
|
// If the given entry is not viewed or selected, remove it from the
|
||||||
* hash, free it, and return 1.
|
// hash, free it, and return 1.
|
||||||
*/
|
//
|
||||||
static int try_free_entry(entry_t *e)
|
static int try_free_entry(entry_t *e)
|
||||||
{
|
{
|
||||||
if (IS_SELECTED(e) || IS_VIEWED(e) || !IS_LOADED(e)) return 0;
|
if (IS_SELECTED(e) || IS_VIEWED(e) || !IS_LOADED(e)) return 0;
|
||||||
@ -989,9 +988,9 @@ static int try_free_entry(entry_t *e)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Sort the files in bb according to bb's settings.
|
// Sort the files in bb according to bb's settings.
|
||||||
*/
|
//
|
||||||
static void sort_files(bb_t *bb)
|
static void sort_files(bb_t *bb)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -1004,10 +1003,10 @@ static void sort_files(bb_t *bb)
|
|||||||
bb->dirty = 1;
|
bb->dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Trim trailing whitespace by inserting '\0' and return a pointer to after the
|
// Trim trailing whitespace by inserting '\0' and return a pointer to after the
|
||||||
* first non-whitespace char
|
// first non-whitespace char
|
||||||
*/
|
//
|
||||||
static char *trim(char *s)
|
static char *trim(char *s)
|
||||||
{
|
{
|
||||||
if (!s) return NULL;
|
if (!s) return NULL;
|
||||||
@ -1018,18 +1017,18 @@ static char *trim(char *s)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Hanlder for SIGWINCH events
|
// Hanlder for SIGWINCH events
|
||||||
*/
|
//
|
||||||
static void update_term_size(int sig)
|
static void update_term_size(int sig)
|
||||||
{
|
{
|
||||||
(void)sig;
|
(void)sig;
|
||||||
ioctl(STDIN_FILENO, TIOCGWINSZ, &winsize);
|
ioctl(STDIN_FILENO, TIOCGWINSZ, &winsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Wait for a process to either suspend or exit and return the status.
|
// Wait for a process to either suspend or exit and return the status.
|
||||||
*/
|
//
|
||||||
static int wait_for_process(proc_t **proc)
|
static int wait_for_process(proc_t **proc)
|
||||||
{
|
{
|
||||||
tcsetpgrp(fileno(tty_out), (*proc)->pid);
|
tcsetpgrp(fileno(tty_out), (*proc)->pid);
|
||||||
|
32
draw.c
32
draw.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
//
|
||||||
* draw.c - This file contains logic for drawing columns.
|
// draw.c - This file contains logic for drawing columns.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -55,11 +55,11 @@ static char* stpcpy_escaped(char *buf, const char *str, const char *color)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Print a string, but replacing bytes like '\n' with a red-colored "\n".
|
// Print a string, but replacing bytes like '\n' with a red-colored "\n".
|
||||||
* The color argument is what color to put back after the red.
|
// The color argument is what color to put back after the red.
|
||||||
* Returns the number of bytes that were escaped.
|
// Returns the number of bytes that were escaped.
|
||||||
*/
|
//
|
||||||
static int fputs_escaped(FILE *f, const char *str, const char *color)
|
static int fputs_escaped(FILE *f, const char *str, const char *color)
|
||||||
{
|
{
|
||||||
static const char *escapes = " abtnvfr e";
|
static const char *escapes = " abtnvfr e";
|
||||||
@ -78,9 +78,9 @@ static int fputs_escaped(FILE *f, const char *str, const char *color)
|
|||||||
return escaped;
|
return escaped;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Returns the color of a file listing, given its mode.
|
// Returns the color of a file listing, given its mode.
|
||||||
*/
|
//
|
||||||
static const char* color_of(mode_t mode)
|
static const char* color_of(mode_t mode)
|
||||||
{
|
{
|
||||||
if (S_ISDIR(mode)) return DIR_COLOR;
|
if (S_ISDIR(mode)) return DIR_COLOR;
|
||||||
@ -280,11 +280,11 @@ void draw_row(FILE *out, char columns[], entry_t *entry, const char *color, int
|
|||||||
fputs("\033[0m", out);
|
fputs("\033[0m", out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Draw everything to the screen.
|
// Draw everything to the screen.
|
||||||
* If `dirty` is false, then use terminal scrolling to move the file listing
|
// If `dirty` is false, then use terminal scrolling to move the file listing
|
||||||
* around and only update the files that have changed.
|
// around and only update the files that have changed.
|
||||||
*/
|
//
|
||||||
void render(FILE *out, bb_t *bb)
|
void render(FILE *out, bb_t *bb)
|
||||||
{
|
{
|
||||||
static int lastcursor = -1, lastscroll = -1;
|
static int lastcursor = -1, lastscroll = -1;
|
||||||
|
6
draw.h
6
draw.h
@ -1,6 +1,6 @@
|
|||||||
/*
|
//
|
||||||
* draw.h - This file contains definitions for bb column-drawing code.
|
// draw.h - This file contains definitions for bb column-drawing code.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#ifndef FILE_COLUMNS__H
|
#ifndef FILE_COLUMNS__H
|
||||||
#define FILE_COLUMNS__H
|
#define FILE_COLUMNS__H
|
||||||
|
40
terminal.c
40
terminal.c
@ -1,11 +1,11 @@
|
|||||||
/*
|
//
|
||||||
* terminal.c
|
// terminal.c
|
||||||
* Copyright 2019 Bruce Hill
|
// Copyright 2019 Bruce Hill
|
||||||
* Released under the MIT License
|
// Released under the MIT License
|
||||||
*
|
//
|
||||||
* Implementations of some basic terminal stuff, like reading keys and some
|
// Implementations of some basic terminal stuff, like reading keys and some
|
||||||
* terminal escape sequences.
|
// terminal escape sequences.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -71,11 +71,11 @@ static inline int nextnum(int fd, int c, int *n)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Get one key of input from the given file. Returns -1 on failure.
|
// Get one key of input from the given file. Returns -1 on failure.
|
||||||
* If mouse_x or mouse_y are non-null and a mouse event occurs, they will be
|
// If mouse_x or mouse_y are non-null and a mouse event occurs, they will be
|
||||||
* set to the position of the mouse (0-indexed).
|
// set to the position of the mouse (0-indexed).
|
||||||
*/
|
//
|
||||||
int bgetkey(FILE *in, int *mouse_x, int *mouse_y)
|
int bgetkey(FILE *in, int *mouse_x, int *mouse_y)
|
||||||
{
|
{
|
||||||
if (mouse_x) *mouse_x = -1;
|
if (mouse_x) *mouse_x = -1;
|
||||||
@ -220,9 +220,9 @@ int bgetkey(FILE *in, int *mouse_x, int *mouse_y)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Populate `buf` with the name of a key.
|
// Populate `buf` with the name of a key.
|
||||||
*/
|
//
|
||||||
char *bkeyname(int key, char *buf)
|
char *bkeyname(int key, char *buf)
|
||||||
{
|
{
|
||||||
if (key & MOD_META) buf = stpcpy(buf, "Super-");
|
if (key & MOD_META) buf = stpcpy(buf, "Super-");
|
||||||
@ -241,10 +241,10 @@ char *bkeyname(int key, char *buf)
|
|||||||
return buf + sprintf(buf, "\\x%02X", key);
|
return buf + sprintf(buf, "\\x%02X", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Return the key with the given name, if one exists, otherwise -1.
|
// Return the key with the given name, if one exists, otherwise -1.
|
||||||
* (i.e. bkeywithname("Space") == ' ', bkeywithname("x") == 'x', bkeywithname("F1") == KEY_F1, bkeywithname("???") == -1)
|
// (i.e. bkeywithname("Space") == ' ', bkeywithname("x") == 'x', bkeywithname("F1") == KEY_F1, bkeywithname("???") == -1)
|
||||||
*/
|
//
|
||||||
int bkeywithname(const char *name)
|
int bkeywithname(const char *name)
|
||||||
{
|
{
|
||||||
int modifiers = 0;
|
int modifiers = 0;
|
||||||
|
44
terminal.h
44
terminal.h
@ -1,11 +1,11 @@
|
|||||||
/*
|
//
|
||||||
* terminal.h
|
// terminal.h
|
||||||
* Copyright 2019 Bruce Hill
|
// Copyright 2019 Bruce Hill
|
||||||
* Released under the MIT License
|
// Released under the MIT License
|
||||||
*
|
//
|
||||||
* Definitions of some basic terminal stuff, like reading keys and some
|
// Definitions of some basic terminal stuff, like reading keys and some
|
||||||
* terminal escape sequences.
|
// terminal escape sequences.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#ifndef FILE__TERMINAL_H
|
#ifndef FILE__TERMINAL_H
|
||||||
#define FILE__TERMINAL_H
|
#define FILE__TERMINAL_H
|
||||||
@ -48,22 +48,22 @@ typedef enum {
|
|||||||
#define MOD_SHIFT (1 << (MOD_BITSHIFT + 3))
|
#define MOD_SHIFT (1 << (MOD_BITSHIFT + 3))
|
||||||
|
|
||||||
// Overlapping key codes:
|
// Overlapping key codes:
|
||||||
#define KEY_CTRL_BACKTICK 0x00 /* clash with ^@ */
|
#define KEY_CTRL_BACKTICK 0x00 // clash with ^@
|
||||||
#define KEY_CTRL_2 0x00 /* clash with ^@ */
|
#define KEY_CTRL_2 0x00 // clash with ^@
|
||||||
#define KEY_BACKSPACE 0x08 /* clash with ^H */
|
#define KEY_BACKSPACE 0x08 // clash with ^H
|
||||||
#define KEY_TAB 0x09 /* clash with ^I */
|
#define KEY_TAB 0x09 // clash with ^I
|
||||||
#define KEY_ENTER 0x0D /* clash with ^M */
|
#define KEY_ENTER 0x0D // clash with ^M
|
||||||
#define KEY_ESC 0x1B /* clash with ^[ */
|
#define KEY_ESC 0x1B // clash with ^[
|
||||||
#define KEY_CTRL_3 0x1B /* clash with ^[ */
|
#define KEY_CTRL_3 0x1B // clash with ^[
|
||||||
#define KEY_CTRL_4 0x1C /* clash with ^\ */
|
#define KEY_CTRL_4 0x1C // clash with ^\
|
||||||
#define KEY_CTRL_5 0x1D /* clash with ^] */
|
#define KEY_CTRL_5 0x1D // clash with ^]
|
||||||
#define KEY_CTRL_TILDE 0x1E /* clash with ^^ */
|
#define KEY_CTRL_TILDE 0x1E // clash with ^^
|
||||||
#define KEY_CTRL_6 0x1E /* clash with ^^ */
|
#define KEY_CTRL_6 0x1E // clash with ^^
|
||||||
#define KEY_CTRL_7 0x1F /* clash with ^_ */
|
#define KEY_CTRL_7 0x1F // clash with ^_
|
||||||
#define KEY_CTRL_SLASH 0x1F /* clash with ^_ */
|
#define KEY_CTRL_SLASH 0x1F // clash with ^_
|
||||||
#define KEY_SPACE 0x20
|
#define KEY_SPACE 0x20
|
||||||
#define KEY_BACKSPACE2 0x7F
|
#define KEY_BACKSPACE2 0x7F
|
||||||
#define KEY_CTRL_8 0x7F /* clash with 'BACKSPACE2' */
|
#define KEY_CTRL_8 0x7F // clash with 'BACKSPACE2'
|
||||||
|
|
||||||
// Terminal escape sequences:
|
// Terminal escape sequences:
|
||||||
#define T_WRAP "7"
|
#define T_WRAP "7"
|
||||||
|
29
types.h
29
types.h
@ -1,10 +1,10 @@
|
|||||||
/*
|
//
|
||||||
* types.h
|
// types.h
|
||||||
* Copyright 2019 Bruce Hill
|
// Copyright 2019 Bruce Hill
|
||||||
* Released under the MIT license
|
// Released under the MIT license
|
||||||
*
|
//
|
||||||
* This file contains definitions of different types.
|
// This file contains definitions of different types.
|
||||||
*/
|
//
|
||||||
#ifndef FILE_TYPES__H
|
#ifndef FILE_TYPES__H
|
||||||
#define FILE_TYPES__H
|
#define FILE_TYPES__H
|
||||||
|
|
||||||
@ -20,13 +20,14 @@
|
|||||||
#define HASH_SIZE 1024
|
#define HASH_SIZE 1024
|
||||||
#define HASH_MASK (HASH_SIZE - 1)
|
#define HASH_MASK (HASH_SIZE - 1)
|
||||||
|
|
||||||
/* Datastructure for file/directory entries.
|
//
|
||||||
* entry_t uses intrusive linked lists. This means entries can only belong to
|
// Datastructure for file/directory entries.
|
||||||
* one list at a time, in this case the list of selected entries. 'atme' is an
|
// entry_t uses intrusive linked lists. This means entries can only belong to
|
||||||
* indirect pointer to either the 'next' field of the previous list member, or
|
// one list at a time, in this case the list of selected entries. 'atme' is an
|
||||||
* the variable that points to the first list member. In other words,
|
// indirect pointer to either the 'next' field of the previous list member, or
|
||||||
* item->next->atme == &item->next and firstitem->atme == &firstitem.
|
// the variable that points to the first list member. In other words,
|
||||||
*/
|
// item->next->atme == &item->next and firstitem->atme == &firstitem.
|
||||||
|
//
|
||||||
typedef struct entry_s {
|
typedef struct entry_s {
|
||||||
struct {
|
struct {
|
||||||
struct entry_s *next, **atme;
|
struct entry_s *next, **atme;
|
||||||
|
14
utils.h
14
utils.h
@ -1,10 +1,10 @@
|
|||||||
/*
|
//
|
||||||
* utils.h
|
// utils.h
|
||||||
* Copyright 2020 Bruce Hill
|
// Copyright 2020 Bruce Hill
|
||||||
* Released under the MIT license
|
// Released under the MIT license
|
||||||
*
|
//
|
||||||
* This file contains some definitions of some utility macros.
|
// This file contains some definitions of some utility macros.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#ifndef FILE_UTILS__H
|
#ifndef FILE_UTILS__H
|
||||||
#define FILE_UTILS__H
|
#define FILE_UTILS__H
|
||||||
|
Loading…
Reference in New Issue
Block a user