1
0
Fork 0
mirror of https://github.com/KingDuckZ/dindexer.git synced 2024-11-29 01:33:46 +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:
King_DuckZ 2016-03-16 00:01:29 +01:00
parent c6b0fe49b5
commit 6991fee7f7
3 changed files with 48 additions and 1 deletions

View file

@ -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
View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
if [ "$3" == "@bare_name@" ]; then
exec @bare_name@ --printactions=$2
fi

View file

@ -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;
} }