its all C now
This commit is contained in:
117
source/main.c
Normal file
117
source/main.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <locale.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include "cli.h"
|
||||
#include "bash_history.yy.h"
|
||||
#include "storage.h"
|
||||
#include "tui.h"
|
||||
|
||||
bool do_run = true;
|
||||
bool do_execute = false;
|
||||
|
||||
void init(void);
|
||||
void deinit(void);
|
||||
|
||||
void init(void) {
|
||||
setlocale(LC_TIME, "C");
|
||||
init_storage();
|
||||
|
||||
char * history_file_path = getenv("HISTFILE");
|
||||
if (!history_file_path) {
|
||||
fputs("$HISTFILE is not set, try exporting it.\n", stderr);
|
||||
deinit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bash_history_in = fopen(history_file_path, "r");
|
||||
if (!bash_history_in) {
|
||||
fputs("Failed to open history file.\n", stderr);
|
||||
deinit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bash_history_lex();
|
||||
|
||||
init_tui();
|
||||
}
|
||||
|
||||
void deinit(void) {
|
||||
deinit_tui();
|
||||
deinit_storage();
|
||||
}
|
||||
|
||||
void export_result(const char * const result) {
|
||||
if (do_execute) {
|
||||
/* Inject the command and a newline to STDIN directly.
|
||||
* Some systems could theoretically be configured to disallow it.
|
||||
* Not my problem.
|
||||
*/
|
||||
for (size_t i = 0; i < strlen(result); i++) {
|
||||
if (ioctl(STDIN_FILENO, TIOCSTI, &result[i]) == -1) {
|
||||
perror("ioctl TIOCSTI");
|
||||
}
|
||||
}
|
||||
const char newline = '\n';
|
||||
ioctl(STDIN_FILENO, TIOCSTI, &newline);
|
||||
} else {
|
||||
/* Copy to a 3th pipe file descriptor which we can
|
||||
* scoop up from a file and copy with READLINE_LINE.
|
||||
* XXX: if anyone knows a better method, please tell me
|
||||
*/
|
||||
int fd[2];
|
||||
int rc = pipe(fd);
|
||||
(void)rc;
|
||||
dprintf(3, result);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void * async([[maybe_unused]] void * arg) {
|
||||
while (do_run) {
|
||||
tui_take_input();
|
||||
if (is_input_changed) {
|
||||
cancel_all_queries();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
signed main(const int argc, const char * const * const argv) {
|
||||
// NOTE: never returns on error
|
||||
parse_arguments(argc, argv);
|
||||
|
||||
init();
|
||||
|
||||
tui_refresh();
|
||||
|
||||
pthread_t query_thread;
|
||||
pthread_create(&query_thread, NULL, async, NULL);
|
||||
while (do_run) {
|
||||
entry_t entry;
|
||||
if (do_redisplay) {
|
||||
do_redisplay = false;
|
||||
if (is_input_changed) {
|
||||
is_input_changed = false;
|
||||
query(rl_line_buffer, entry_lines, selection_offset);
|
||||
} else {
|
||||
requery();
|
||||
}
|
||||
while (entry = get_entry(), entry.command != NULL) {
|
||||
tui_append_back(entry);
|
||||
}
|
||||
tui_refresh();
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
pthread_join(query_thread, NULL);
|
||||
|
||||
query(rl_line_buffer, 1, selection_offset + selection_relative);
|
||||
export_result(get_entry().command);
|
||||
|
||||
deinit();
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user