mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2024-11-25 00:53:43 +00:00
Add support for bash autocomplete in main dindexer
I'm not sure this is something that should be in the code, since compgen -W "delete locate navigate query scan" loc would do just the same as dindexer --printactions=loc so this is a duplicated functionality. However this commit is self-contained, so it should be easy to revert it, if needed.
This commit is contained in:
parent
c6b0fe49b5
commit
6991fee7f7
3 changed files with 48 additions and 1 deletions
|
@ -61,6 +61,11 @@ configure_file(
|
||||||
"${PROJECT_SOURCE_DIR}/dindexer.sql.in"
|
"${PROJECT_SOURCE_DIR}/dindexer.sql.in"
|
||||||
"${PROJECT_BINARY_DIR}/dindexer.sql"
|
"${PROJECT_BINARY_DIR}/dindexer.sql"
|
||||||
)
|
)
|
||||||
|
configure_file(
|
||||||
|
"${PROJECT_SOURCE_DIR}/dindexer_cmd_complete.sh.in"
|
||||||
|
"${PROJECT_BINARY_DIR}/dindexer_cmd_complete.sh"
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} SYSTEM
|
target_include_directories(${PROJECT_NAME} SYSTEM
|
||||||
INTERFACE ${Boost_INCLUDE_DIRS}
|
INTERFACE ${Boost_INCLUDE_DIRS}
|
||||||
|
|
4
dindexer_cmd_complete.sh.in
Executable file
4
dindexer_cmd_complete.sh.in
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ "$3" == "@bare_name@" ]; then
|
||||||
|
exec @bare_name@ --printactions=$2
|
||||||
|
fi
|
|
@ -28,8 +28,16 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
|
struct PrintContext {
|
||||||
|
FILE* stream;
|
||||||
|
char* prefix_filter;
|
||||||
|
int add_space;
|
||||||
|
};
|
||||||
|
typedef struct PrintContext PrintContext;
|
||||||
|
|
||||||
static size_t foreach_avail_action ( int(*parFunc)(const char*, const void*), char** parList, size_t parCount, const void* parPass );
|
static size_t foreach_avail_action ( int(*parFunc)(const char*, const void*), char** parList, size_t parCount, const void* parPass );
|
||||||
static int printf_stream ( const char* parMsg, const void* parStream );
|
static int printf_stream ( const char* parMsg, const void* parStream );
|
||||||
|
static int printf_stream_inplace ( const char* parMsg, const void* parPrintContext );
|
||||||
static int same_action ( const char* parAction1, const void* parAction2 );
|
static int same_action ( const char* parAction1, const void* parAction2 );
|
||||||
static void print_usage ( void );
|
static void print_usage ( void );
|
||||||
static int manage_commandline ( int parArgc, char* parArgv[], char** parActions, size_t parActionCount, int* parShouldQuit );
|
static int manage_commandline ( int parArgc, char* parArgv[], char** parActions, size_t parActionCount, int* parShouldQuit );
|
||||||
|
@ -125,6 +133,19 @@ static int printf_stream (const char* parMsg, const void* parStream) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int printf_stream_inplace (const char* parMsg, const void* parPrintContext) {
|
||||||
|
size_t prefix_len;
|
||||||
|
struct PrintContext* context = (PrintContext*)parPrintContext;
|
||||||
|
const char* separator = (context->add_space ? "\n" : "");
|
||||||
|
|
||||||
|
prefix_len = (context->prefix_filter ? strlen(context->prefix_filter) : 0);
|
||||||
|
if (0 == prefix_len or strncmp(context->prefix_filter, parMsg, prefix_len) == 0) {
|
||||||
|
context->add_space = 1;
|
||||||
|
fprintf(context->stream, "%s%s", separator, parMsg);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int same_action (const char* parAction1, const void* parAction2) {
|
static int same_action (const char* parAction1, const void* parAction2) {
|
||||||
const char* const action2 = (const char*)parAction2;
|
const char* const action2 = (const char*)parAction2;
|
||||||
if (0 == strcmp(parAction1, action2)) {
|
if (0 == strcmp(parAction1, action2)) {
|
||||||
|
@ -138,25 +159,31 @@ static int same_action (const char* parAction1, const void* parAction2) {
|
||||||
static void print_usage() {
|
static void print_usage() {
|
||||||
printf("--help, -h - show this help\n");
|
printf("--help, -h - show this help\n");
|
||||||
printf("--builtin, -b - show build info\n");
|
printf("--builtin, -b - show build info\n");
|
||||||
|
printf("--printactions=[prefix] - print a complete-friendly list of available commands, filtered by an optional prefix\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manage_commandline (int parArgc, char* parArgv[], char** parActions, size_t parActionCount, int* parShouldQuit) {
|
static int manage_commandline (int parArgc, char* parArgv[], char** parActions, size_t parActionCount, int* parShouldQuit) {
|
||||||
int showbuiltin;
|
int showbuiltin;
|
||||||
int showhelp;
|
int showhelp;
|
||||||
|
int showactions_for_completion;
|
||||||
int option_index;
|
int option_index;
|
||||||
int getopt_retval;
|
int getopt_retval;
|
||||||
FILE* streamout;
|
FILE* streamout;
|
||||||
int retval;
|
int retval;
|
||||||
|
struct PrintContext actions_print_context;
|
||||||
|
|
||||||
struct option opts[] = {
|
struct option opts[] = {
|
||||||
|
{ "printactions", optional_argument, NULL, 'a' },
|
||||||
{ "builtin", no_argument, &showbuiltin, 1 },
|
{ "builtin", no_argument, &showbuiltin, 1 },
|
||||||
{ "help", no_argument, &showhelp, 1 },
|
{ "help", no_argument, &showhelp, 1 },
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
memset(&actions_print_context, 0, sizeof(actions_print_context));
|
||||||
option_index = 0;
|
option_index = 0;
|
||||||
showbuiltin = showhelp = 0;
|
showbuiltin = showhelp = showactions_for_completion = 0;
|
||||||
*parShouldQuit = 0;
|
*parShouldQuit = 0;
|
||||||
|
|
||||||
while (0 <= (getopt_retval = getopt_long(parArgc, parArgv, "bh", opts, &option_index))) {
|
while (0 <= (getopt_retval = getopt_long(parArgc, parArgv, "bh", opts, &option_index))) {
|
||||||
switch (getopt_retval) {
|
switch (getopt_retval) {
|
||||||
case 'h':
|
case 'h':
|
||||||
|
@ -168,6 +195,9 @@ static int manage_commandline (int parArgc, char* parArgv[], char** parActions,
|
||||||
case '?':
|
case '?':
|
||||||
*parShouldQuit = 1;
|
*parShouldQuit = 1;
|
||||||
return 2;
|
return 2;
|
||||||
|
case 'a':
|
||||||
|
showactions_for_completion = 1;
|
||||||
|
actions_print_context.prefix_filter = (optarg ? optarg : "");
|
||||||
}
|
}
|
||||||
option_index = 0;
|
option_index = 0;
|
||||||
}
|
}
|
||||||
|
@ -194,5 +224,13 @@ static int manage_commandline (int parArgc, char* parArgv[], char** parActions,
|
||||||
print_builtin_feats();
|
print_builtin_feats();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (showactions_for_completion) {
|
||||||
|
*parShouldQuit = 1;
|
||||||
|
actions_print_context.stream = stdout;
|
||||||
|
foreach_avail_action(&printf_stream_inplace, parActions, parActionCount, &actions_print_context);
|
||||||
|
if (actions_print_context.add_space) {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue