--input
This commit is contained in:
parent
8e6f183116
commit
bc107d59a7
@ -1,12 +1,16 @@
|
||||
%token HELP VERSION EXECUTE
|
||||
%token TUI ENABLE
|
||||
%token FUZZY CASELESS GROUP
|
||||
%token FUZZY CASELESS GROUP INPUT
|
||||
%{
|
||||
#include <stdlib.h>
|
||||
#include "cli.h"
|
||||
#include "tui.h"
|
||||
#include "storage.h"
|
||||
extern bool do_execute;
|
||||
extern bool is_expecting_argument;
|
||||
%}
|
||||
%union { const char * strval; }
|
||||
%token<strval> ARGUMENT
|
||||
%%
|
||||
histui_args: global_args verb_and_args
|
||||
;
|
||||
@ -25,6 +29,8 @@ tui_args: %empty
|
||||
| FUZZY tui_args { is_fuzzy = true; }
|
||||
| CASELESS tui_args { is_caseless = 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"
|
||||
|
||||
int * arg_tokens;
|
||||
bool is_expecting_argument = false;
|
||||
|
||||
static int yy_argc;
|
||||
static const char * const * yy_argv;
|
||||
static int yy_i;
|
||||
|
||||
void version() {
|
||||
puts(
|
||||
@ -41,7 +45,7 @@ void enable(void) {
|
||||
" if ! [ -v HISTUICMD ]; then\n"
|
||||
" HISTUICMD=\"histui tui\"\n"
|
||||
" fi\n"
|
||||
" HISTFILE=$HISTFILE ${HISTUICMD} 3> \"${COMMANDFILE}\"\n"
|
||||
" HISTFILE=$HISTFILE ${HISTUICMD} --input \"${READLINE_LINE}\" 3> \"${COMMANDFILE}\"\n"
|
||||
" READLINE_LINE=$(cat \"${COMMANDFILE}\")\n"
|
||||
" READLINE_POINT=${#READLINE_LINE}\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) {
|
||||
static int i = 0;
|
||||
return arg_tokens[i++];
|
||||
for (; yy_i < yy_argc;) {
|
||||
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) {
|
||||
@ -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) {
|
||||
#if 0
|
||||
argument_yy_debug = 1;
|
||||
#endif
|
||||
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* 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).
|
||||
*/
|
||||
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;
|
||||
yy_argc = argc - 1;
|
||||
yy_argv = argv + 1;
|
||||
|
||||
argument_yy_parse();
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ signed main(const int argc, const char * const * const argv) {
|
||||
do_redisplay = false;
|
||||
if (is_input_changed) {
|
||||
is_input_changed = false;
|
||||
query(rl_line_buffer, entry_lines, selection_offset);
|
||||
query(get_input_line(), entry_lines, selection_offset);
|
||||
} else {
|
||||
requery();
|
||||
}
|
||||
@ -106,7 +106,7 @@ signed main(const int argc, const char * const * const argv) {
|
||||
}
|
||||
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);
|
||||
|
||||
deinit();
|
||||
|
13
source/tui.c
13
source/tui.c
@ -8,6 +8,17 @@
|
||||
|
||||
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
|
||||
*/
|
||||
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 return_input_available(void) { return input_available; }
|
||||
int initializer(void) { rl_insert_text(initial_text); return 0; }
|
||||
rl_getc_function = getc_function;
|
||||
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 ;
|
||||
* we cannot null this function.
|
||||
* Im seriously questioning why readline is still the """default""" library in the wild
|
||||
|
@ -4,7 +4,8 @@
|
||||
#include <stddef.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 selection_offset;
|
||||
|
Loading…
x
Reference in New Issue
Block a user