--input
This commit is contained in:
@ -1,12 +1,16 @@
|
|||||||
%token HELP VERSION EXECUTE
|
%token HELP VERSION EXECUTE
|
||||||
%token TUI ENABLE
|
%token TUI ENABLE
|
||||||
%token FUZZY CASELESS GROUP
|
%token FUZZY CASELESS GROUP INPUT
|
||||||
%{
|
%{
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
|
#include "tui.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
extern bool do_execute;
|
extern bool do_execute;
|
||||||
|
extern bool is_expecting_argument;
|
||||||
%}
|
%}
|
||||||
|
%union { const char * strval; }
|
||||||
|
%token<strval> ARGUMENT
|
||||||
%%
|
%%
|
||||||
histui_args: global_args verb_and_args
|
histui_args: global_args verb_and_args
|
||||||
;
|
;
|
||||||
@ -25,6 +29,8 @@ tui_args: %empty
|
|||||||
| FUZZY tui_args { is_fuzzy = true; }
|
| FUZZY tui_args { is_fuzzy = true; }
|
||||||
| CASELESS tui_args { is_caseless = true; }
|
| CASELESS tui_args { is_caseless = true; }
|
||||||
| GROUP tui_args { is_grouped = true; }
|
| GROUP tui_args { is_grouped = true; }
|
||||||
|
| input ARGUMENT tui_args { initial_text = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
input: INPUT { is_expecting_argument = true; }
|
||||||
%%
|
%%
|
||||||
|
103
source/cli.c
103
source/cli.c
@ -6,7 +6,11 @@
|
|||||||
|
|
||||||
#include "argument_yy.tab.h"
|
#include "argument_yy.tab.h"
|
||||||
|
|
||||||
int * arg_tokens;
|
bool is_expecting_argument = false;
|
||||||
|
|
||||||
|
static int yy_argc;
|
||||||
|
static const char * const * yy_argv;
|
||||||
|
static int yy_i;
|
||||||
|
|
||||||
void version() {
|
void version() {
|
||||||
puts(
|
puts(
|
||||||
@ -41,7 +45,7 @@ void enable(void) {
|
|||||||
" if ! [ -v HISTUICMD ]; then\n"
|
" if ! [ -v HISTUICMD ]; then\n"
|
||||||
" HISTUICMD=\"histui tui\"\n"
|
" HISTUICMD=\"histui tui\"\n"
|
||||||
" fi\n"
|
" fi\n"
|
||||||
" HISTFILE=$HISTFILE ${HISTUICMD} 3> \"${COMMANDFILE}\"\n"
|
" HISTFILE=$HISTFILE ${HISTUICMD} --input \"${READLINE_LINE}\" 3> \"${COMMANDFILE}\"\n"
|
||||||
" READLINE_LINE=$(cat \"${COMMANDFILE}\")\n"
|
" READLINE_LINE=$(cat \"${COMMANDFILE}\")\n"
|
||||||
" READLINE_POINT=${#READLINE_LINE}\n"
|
" READLINE_POINT=${#READLINE_LINE}\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
@ -51,9 +55,54 @@ void enable(void) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lexical analysis of a poor man.
|
||||||
|
* Using Flex would be problematic because our input
|
||||||
|
* is not stored in an actual buffer (not in a defined
|
||||||
|
* behaviour way anyways).
|
||||||
|
*/
|
||||||
|
#define YIELD(v) ++yy_i; return v
|
||||||
int argument_yy_lex(void) {
|
int argument_yy_lex(void) {
|
||||||
static int i = 0;
|
for (; yy_i < yy_argc;) {
|
||||||
return arg_tokens[i++];
|
if (is_expecting_argument) {
|
||||||
|
is_expecting_argument = false;
|
||||||
|
argument_yy_lval.strval = yy_argv[yy_i];
|
||||||
|
YIELD(ARGUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(yy_argv[yy_i], "--help")
|
||||||
|
|| !strcmp(yy_argv[yy_i], "-h")) {
|
||||||
|
YIELD(HELP);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "--version")
|
||||||
|
|| !strcmp(yy_argv[yy_i], "-v")) {
|
||||||
|
YIELD(VERSION);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "tui")) {
|
||||||
|
YIELD(TUI);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "enable")) {
|
||||||
|
YIELD(ENABLE);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "--execute")) {
|
||||||
|
YIELD(EXECUTE);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "--fuzzy")) {
|
||||||
|
YIELD(FUZZY);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "--caseless")) {
|
||||||
|
YIELD(CASELESS);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "--group")) {
|
||||||
|
YIELD(GROUP);
|
||||||
|
} else
|
||||||
|
if (!strcmp(yy_argv[yy_i], "--input")) {
|
||||||
|
YIELD(INPUT);
|
||||||
|
} else {
|
||||||
|
YIELD(YYUNDEF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YIELD(YYEOF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void argument_yy_error([[ maybe_unused ]] const char * const s) {
|
void argument_yy_error([[ maybe_unused ]] const char * const s) {
|
||||||
@ -63,51 +112,17 @@ void argument_yy_error([[ maybe_unused ]] const char * const s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void parse_arguments(const int argc, const char * const * const argv) {
|
void parse_arguments(const int argc, const char * const * const argv) {
|
||||||
|
#if 0
|
||||||
|
argument_yy_debug = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lexical analysis of a poor man.
|
yy_argc = argc - 1;
|
||||||
* Using Flex would be problematic because our input
|
yy_argv = argv + 1;
|
||||||
* is not stored in an actual buffer (not in a defined
|
|
||||||
* behaviour way anyways).
|
|
||||||
*/
|
|
||||||
int tokens[argc];
|
|
||||||
int token_empty_head = 0;
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (!strcmp(argv[i], "--help")
|
|
||||||
|| !strcmp(argv[i], "-h")) {
|
|
||||||
tokens[token_empty_head++] = HELP;
|
|
||||||
} else
|
|
||||||
if (!strcmp(argv[i], "--version")
|
|
||||||
|| !strcmp(argv[i], "-v")) {
|
|
||||||
tokens[token_empty_head++] = VERSION;
|
|
||||||
} else
|
|
||||||
if (!strcmp(argv[i], "tui")) {
|
|
||||||
tokens[token_empty_head++] = TUI;
|
|
||||||
} else
|
|
||||||
if (!strcmp(argv[i], "enable")) {
|
|
||||||
tokens[token_empty_head++] = ENABLE;
|
|
||||||
} else
|
|
||||||
if (!strcmp(argv[i], "--execute")) {
|
|
||||||
tokens[token_empty_head++] = EXECUTE;
|
|
||||||
} else
|
|
||||||
if (!strcmp(argv[i], "--fuzzy")) {
|
|
||||||
tokens[token_empty_head++] = FUZZY;
|
|
||||||
} else
|
|
||||||
if (!strcmp(argv[i], "--caseless")) {
|
|
||||||
tokens[token_empty_head++] = CASELESS;
|
|
||||||
} else
|
|
||||||
if (!strcmp(argv[i], "--group")) {
|
|
||||||
tokens[token_empty_head++] = GROUP;
|
|
||||||
} else {
|
|
||||||
tokens[token_empty_head++] = YYUNDEF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens[token_empty_head++] = YYEOF;
|
|
||||||
|
|
||||||
arg_tokens = tokens;
|
|
||||||
|
|
||||||
argument_yy_parse();
|
argument_yy_parse();
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ signed main(const int argc, const char * const * const argv) {
|
|||||||
do_redisplay = false;
|
do_redisplay = false;
|
||||||
if (is_input_changed) {
|
if (is_input_changed) {
|
||||||
is_input_changed = false;
|
is_input_changed = false;
|
||||||
query(rl_line_buffer, entry_lines, selection_offset);
|
query(get_input_line(), entry_lines, selection_offset);
|
||||||
} else {
|
} else {
|
||||||
requery();
|
requery();
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ signed main(const int argc, const char * const * const argv) {
|
|||||||
}
|
}
|
||||||
pthread_join(query_thread, NULL);
|
pthread_join(query_thread, NULL);
|
||||||
|
|
||||||
query(rl_line_buffer, 1, selection_offset + selection_relative);
|
query(get_input_line(), 1, selection_offset + selection_relative);
|
||||||
export_result(get_entry().command);
|
export_result(get_entry().command);
|
||||||
|
|
||||||
deinit();
|
deinit();
|
||||||
|
13
source/tui.c
13
source/tui.c
@ -8,6 +8,17 @@
|
|||||||
|
|
||||||
extern bool do_execute;
|
extern bool do_execute;
|
||||||
|
|
||||||
|
/* I fucking hate readline.
|
||||||
|
* Apparently the only way to set an initial value is using a hook.
|
||||||
|
* What makes this extra painful is that readline cannot be explicitly
|
||||||
|
* initialized nor is it documented clearly that shit will segfault
|
||||||
|
* otherwise.
|
||||||
|
* If I ever find out what is a sensible alternative im ditching it forever.
|
||||||
|
*/
|
||||||
|
const char * initial_text;
|
||||||
|
|
||||||
|
const char * get_input_line(void) { return rl_line_buffer; }
|
||||||
|
|
||||||
/* "Cursor" position; the entry selected by the user
|
/* "Cursor" position; the entry selected by the user
|
||||||
*/
|
*/
|
||||||
size_t selection_relative = 0;
|
size_t selection_relative = 0;
|
||||||
@ -71,8 +82,10 @@ int init_tui(void) {
|
|||||||
|
|
||||||
int getc_function([[maybe_unused]] FILE* ignore) { input_available = false; return (int)(input); }
|
int getc_function([[maybe_unused]] FILE* ignore) { input_available = false; return (int)(input); }
|
||||||
int return_input_available(void) { return input_available; }
|
int return_input_available(void) { return input_available; }
|
||||||
|
int initializer(void) { rl_insert_text(initial_text); return 0; }
|
||||||
rl_getc_function = getc_function;
|
rl_getc_function = getc_function;
|
||||||
rl_input_available_hook = return_input_available;
|
rl_input_available_hook = return_input_available;
|
||||||
|
rl_startup_hook = initializer;
|
||||||
/* Due to this bug: https://mail.gnu.org/archive/html/bug-readline/2013-09/msg00021.html ;
|
/* Due to this bug: https://mail.gnu.org/archive/html/bug-readline/2013-09/msg00021.html ;
|
||||||
* we cannot null this function.
|
* we cannot null this function.
|
||||||
* Im seriously questioning why readline is still the """default""" library in the wild
|
* Im seriously questioning why readline is still the """default""" library in the wild
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
extern char * rl_line_buffer;
|
extern const char * initial_text;
|
||||||
|
extern const char * get_input_line(void);
|
||||||
|
|
||||||
extern size_t entry_lines;
|
extern size_t entry_lines;
|
||||||
extern size_t selection_offset;
|
extern size_t selection_offset;
|
||||||
|
Reference in New Issue
Block a user