Save off command and buffer history, allow for resumption
This commit is contained in:
parent
f8bc3534fc
commit
17f268d78a
6 changed files with 93 additions and 50 deletions
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
static int parse_args(int argc, char **argv);
|
||||
static int load_configs();
|
||||
static int read_state();
|
||||
static int load_state();
|
||||
static speed_t string_to_speed(const char *speed);
|
||||
static const char *speed_to_string(speed_t speed);
|
||||
|
|
@ -49,6 +50,10 @@ bytenuts_run(int argc, char **argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (bytenuts.resume) {
|
||||
read_state();
|
||||
}
|
||||
|
||||
bytenuts.serial_fd = serial_open(bytenuts.config.serial_path, bytenuts.config.baud);
|
||||
if (bytenuts.serial_fd < 0) {
|
||||
return -1;
|
||||
|
|
@ -109,6 +114,13 @@ bytenuts_run(int argc, char **argv)
|
|||
|
||||
if (bytenuts.resume) {
|
||||
load_state();
|
||||
} else {
|
||||
cheerios_insert(
|
||||
"Welcome to Bytenuts\r\n"
|
||||
"To quit press ctrl-b q\r\n"
|
||||
"To see all commands, press ctrl-b h\r\n",
|
||||
82
|
||||
);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&bytenuts.lock);
|
||||
|
|
@ -392,54 +404,70 @@ load_configs()
|
|||
}
|
||||
|
||||
static int
|
||||
load_state()
|
||||
read_state()
|
||||
{
|
||||
struct stat st;
|
||||
char *buf;
|
||||
char *cwd = getcwd(NULL, 0);
|
||||
char *home = getenv("HOME");
|
||||
FILE *fd;
|
||||
|
||||
buf = calloc(1, snprintf(NULL, 0, "%s/.config/bytenuts/inbuf.log", home) + 1);
|
||||
sprintf(buf, "%s/.config/bytenuts/inbuf.log", home);
|
||||
fd = fopen(buf, "r");
|
||||
stat(buf, &st);
|
||||
free(buf);
|
||||
|
||||
if (fd) {
|
||||
char **history = NULL;
|
||||
int history_len = 0;
|
||||
chdir(home);
|
||||
|
||||
fd = fopen(".config/bytenuts/inbuf.log", "r");
|
||||
stat(".config/bytenuts/inbuf.log", &st);
|
||||
if (fd && st.st_size > 0) {
|
||||
buf = calloc(1, st.st_size + 1);
|
||||
while (fgets(buf, st.st_size+1, fd)) {
|
||||
history_len++;
|
||||
history = realloc(history, sizeof(char *) * history_len);
|
||||
history[history_len-1] = strdup(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
if (history) {
|
||||
ingest_set_history(history);
|
||||
for (int i = 0; i < history_len; i++) {
|
||||
free(history[i]);
|
||||
}
|
||||
free(history);
|
||||
bytenuts.state.history_len++;
|
||||
bytenuts.state.history = realloc(
|
||||
bytenuts.state.history,
|
||||
sizeof(char *) * bytenuts.state.history_len
|
||||
);
|
||||
bytenuts.state.history[bytenuts.state.history_len-1] = strdup(buf);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
buf = calloc(1, snprintf(NULL, 0, "%s/.config/bytenuts/outbuf.log", home) + 1);
|
||||
sprintf(buf, "%s/.config/bytenuts/outbuf.log", home);
|
||||
fd = fopen(buf, "r");
|
||||
stat(buf, &st);
|
||||
free(buf);
|
||||
|
||||
if (fd) {
|
||||
buf = malloc(st.st_size);
|
||||
fread(buf, 1, st.st_size, fd);
|
||||
cheerios_insert(buf, st.st_size);
|
||||
free(buf);
|
||||
if (fd)
|
||||
fclose(fd);
|
||||
|
||||
stat(".config/bytenuts/outbuf.log", &st);
|
||||
fd = fopen(".config/bytenuts/outbuf.log", "r");
|
||||
|
||||
if (fd && st.st_size > 0) {
|
||||
bytenuts.state.buf = malloc(st.st_size);
|
||||
bytenuts.state.buf_len = st.st_size;
|
||||
fread(bytenuts.state.buf, 1, st.st_size, fd);
|
||||
}
|
||||
if (fd)
|
||||
fclose(fd);
|
||||
|
||||
chdir(cwd);
|
||||
free(cwd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
load_state()
|
||||
{
|
||||
if (bytenuts.state.history) {
|
||||
ingest_set_history(bytenuts.state.history, bytenuts.state.history_len);
|
||||
|
||||
for (int i = 0; i < bytenuts.state.history_len; i++) {
|
||||
free(bytenuts.state.history[i]);
|
||||
}
|
||||
free(bytenuts.state.history);
|
||||
bytenuts.state.history = NULL;
|
||||
bytenuts.state.history_len = 0;
|
||||
}
|
||||
|
||||
if (bytenuts.state.buf) {
|
||||
cheerios_insert(bytenuts.state.buf, bytenuts.state.buf_len);
|
||||
free(bytenuts.state.buf);
|
||||
bytenuts.state.buf = NULL;
|
||||
bytenuts.state.buf_len = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@
|
|||
/* https://en.wikipedia.org/wiki/Control_character#How_control_characters_map_to_keyboards */
|
||||
#define CTRL(c) ((c)&31)
|
||||
|
||||
typedef struct bytenuts_state_struct {
|
||||
char **history; /* commands from previous session */
|
||||
int history_len;
|
||||
char *buf; /* previous buffer */
|
||||
size_t buf_len;
|
||||
} bytenuts_state_t;
|
||||
|
||||
typedef struct bytenuts_config_struct {
|
||||
int colors; /* enable terminal colors, default 1 */
|
||||
int echo; /* echo user input to the output window, default 0 */
|
||||
|
|
@ -38,6 +45,7 @@ typedef struct bytenuts_struct {
|
|||
bytenuts_config_t config;
|
||||
int config_overrides[4];
|
||||
int resume;
|
||||
bytenuts_state_t state;
|
||||
WINDOW *status_win;
|
||||
WINDOW *out_win;
|
||||
WINDOW *in_win;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ static int newline(line_buffer_t *lines);
|
|||
int
|
||||
cheerios_start(bytenuts_t *bytenuts)
|
||||
{
|
||||
char *home;
|
||||
char *home = getenv("HOME");
|
||||
char *cwd;
|
||||
|
||||
memset(&cheerios, 0, sizeof(cheerios_t));
|
||||
|
|
|
|||
34
src/ingest.c
34
src/ingest.c
|
|
@ -81,7 +81,7 @@ ingest_stop()
|
|||
}
|
||||
|
||||
int
|
||||
ingest_set_history(char **history)
|
||||
ingest_set_history(char **history, int history_len)
|
||||
{
|
||||
if (ingest.history) {
|
||||
for (int i = 0; ingest.history[i] != NULL; i++) {
|
||||
|
|
@ -90,16 +90,28 @@ ingest_set_history(char **history)
|
|||
free(ingest.history);
|
||||
}
|
||||
|
||||
ingest.history = calloc(1, sizeof(char *));
|
||||
for (int i = 0; history[i] != NULL; i++) {
|
||||
ingest.history = realloc(
|
||||
ingest.history,
|
||||
(i+2) * sizeof(char *)
|
||||
);
|
||||
ingest.history = calloc(1, sizeof(char *) * (history_len+1));
|
||||
for (int i = 0; i < history_len; i++) {
|
||||
size_t item_len = strlen(history[i]);
|
||||
ingest.history[i] = strdup(history[i]);
|
||||
ingest.history[i+1] = NULL;
|
||||
|
||||
while (
|
||||
ingest.history[i][item_len-1] == '\n' ||
|
||||
ingest.history[i][item_len-1] == '\r'
|
||||
) {
|
||||
item_len--;
|
||||
ingest.history[i][item_len] = '\0';
|
||||
}
|
||||
|
||||
if (ingest.history_fd) {
|
||||
fwrite(ingest.history[i], 1, item_len, ingest.history_fd);
|
||||
fwrite("\n", 1, 1, ingest.history_fd);
|
||||
}
|
||||
}
|
||||
|
||||
ingest.history_len = history_len;
|
||||
ingest.history_pos = ingest.history_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -112,12 +124,6 @@ ingest_thread(void *arg)
|
|||
memset(ingest.inbuf, 0, sizeof(ingest.inbuf));
|
||||
ingest.inpos = 0;
|
||||
|
||||
cheerios_insert(
|
||||
"Welcome to Bytenuts\r\n"
|
||||
"To quit press ctrl-b q\r\n"
|
||||
"To see all commands, press ctrl-b h\r\n",
|
||||
82
|
||||
);
|
||||
bytenuts_set_status(STATUS_INGEST, "normal");
|
||||
|
||||
while (ingest.running) {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ typedef struct ingest_struct {
|
|||
pthread_t thr;
|
||||
volatile int running;
|
||||
char *prepend; /* string to be prepended in the prompt */
|
||||
char inbuf[1024];
|
||||
char inbuf[4096];
|
||||
int inpos; /* cursor position within the inbuf itself */
|
||||
int inlen; /* length of the input buffer */
|
||||
char **history; /* array of strings representing the command history */
|
||||
FILE *history_fd;
|
||||
char tmp_history[1024]; /* copy of inbuf before we load in history */
|
||||
char tmp_history[4096]; /* copy of inbuf before we load in history */
|
||||
int history_len;
|
||||
int history_pos; /* where we currently reside in the history */
|
||||
int mode;
|
||||
|
|
@ -47,6 +47,6 @@ int ingest_start(bytenuts_t *bytenuts);
|
|||
int ingest_stop();
|
||||
|
||||
/* Set the the command history directly. Values are copied */
|
||||
int ingest_set_history(char **history);
|
||||
int ingest_set_history(char **history, int history_len);
|
||||
|
||||
#endif /* _INGEST_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue