Add shell completion of sub-configuration names

Does not work with sub configuration names that contains one or more
white spaces.
This commit is contained in:
Martin Lund 2022-10-16 23:01:08 +02:00
parent bf7b032649
commit a97b2c00cd
6 changed files with 90 additions and 30 deletions

View file

@ -159,12 +159,14 @@ _tio()
;; ;;
esac esac
sub_configs="`tio --complete-sub-configs`"
if [ -d /dev/serial/by-id ]; then if [ -d /dev/serial/by-id ]; then
ttys=$(printf '%s\n' /dev/tty* /dev/serial/by-id/*) ttys=$(printf '%s\n' /dev/tty* /dev/serial/by-id/*)
else else
ttys=$(printf '%s\n' /dev/tty*) ttys=$(printf '%s\n' /dev/tty*)
fi fi
COMPREPLY=( $(compgen -W "${ttys}" -- ${cur}) ) COMPREPLY=( $(compgen -W "${ttys} ${sub_configs}" -- ${cur}) )
return 0 return 0
} }

View file

@ -342,6 +342,24 @@ static int section_name_search_handler(void *user, const char *section, const ch
return 0; return 0;
} }
static int section_name_print_handler(void *user, const char *section, const char *varname,
const char *varval)
{
UNUSED(user);
UNUSED(varname);
UNUSED(varval);
static char *section_previous = "";
if (strcmp(section, section_previous) != 0)
{
printf("%s ", section);
section_previous = strdup(section);
}
return 0;
}
static int resolve_config_file(void) static int resolve_config_file(void)
{ {
asprintf(&c->path, "%s/tio/tiorc", getenv("XDG_CONFIG_HOME")); asprintf(&c->path, "%s/tio/tiorc", getenv("XDG_CONFIG_HOME"));
@ -373,6 +391,26 @@ static int resolve_config_file(void)
return -EINVAL; return -EINVAL;
} }
void config_file_show_sub_configurations(void)
{
c = malloc(sizeof(struct config_t));
if (!c)
{
tio_error_printf("Insufficient memory allocation");
exit(EXIT_FAILURE);
}
memset(c, 0, sizeof(struct config_t));
// Find config file
if (resolve_config_file() != 0)
{
// None found - stop parsing
return;
}
ini_parse(c->path, section_name_print_handler, NULL);
}
void config_file_parse(void) void config_file_parse(void)
{ {
int ret; int ret;

View file

@ -41,3 +41,4 @@ struct config_t
void config_file_print(void); void config_file_print(void);
void config_file_parse(void); void config_file_parse(void);
void config_exit(void); void config_exit(void);
void config_file_show_sub_configurations(void);

View file

@ -45,6 +45,12 @@ int main(int argc, char *argv[])
/* Parse command-line options (1st pass) */ /* Parse command-line options (1st pass) */
options_parse(argc, argv); options_parse(argc, argv);
if (option.complete_sub_configs)
{
config_file_show_sub_configurations();
return status;
}
/* Parse configuration file */ /* Parse configuration file */
config_file_parse(); config_file_parse();

View file

@ -50,6 +50,7 @@ enum opt_t
OPT_RS485, OPT_RS485,
OPT_RS485_CONFIG, OPT_RS485_CONFIG,
OPT_ALERT, OPT_ALERT,
OPT_COMPLETE_SUB_CONFIGS,
}; };
/* Default options */ /* Default options */
@ -89,6 +90,7 @@ struct option_t option =
.rs485_delay_rts_before_send = -1, .rs485_delay_rts_before_send = -1,
.rs485_delay_rts_after_send = -1, .rs485_delay_rts_after_send = -1,
.alert = ALERT_NONE, .alert = ALERT_NONE,
.complete_sub_configs = false,
}; };
void print_help(char *argv[]) void print_help(char *argv[])
@ -229,34 +231,35 @@ void options_parse(int argc, char *argv[])
{ {
static struct option long_options[] = static struct option long_options[] =
{ {
{"baudrate", required_argument, 0, 'b' }, {"baudrate", required_argument, 0, 'b' },
{"databits", required_argument, 0, 'd' }, {"databits", required_argument, 0, 'd' },
{"flow", required_argument, 0, 'f' }, {"flow", required_argument, 0, 'f' },
{"stopbits", required_argument, 0, 's' }, {"stopbits", required_argument, 0, 's' },
{"parity", required_argument, 0, 'p' }, {"parity", required_argument, 0, 'p' },
{"output-delay", required_argument, 0, 'o' }, {"output-delay", required_argument, 0, 'o' },
{"output-line-delay" , required_argument, 0, 'O' }, {"output-line-delay" , required_argument, 0, 'O' },
{"line-pulse-duration", required_argument, 0, OPT_LINE_PULSE_DURATION}, {"line-pulse-duration", required_argument, 0, OPT_LINE_PULSE_DURATION },
{"no-autoconnect", no_argument, 0, 'n' }, {"no-autoconnect", no_argument, 0, 'n' },
{"local-echo", no_argument, 0, 'e' }, {"local-echo", no_argument, 0, 'e' },
{"timestamp", no_argument, 0, 't' }, {"timestamp", no_argument, 0, 't' },
{"timestamp-format", required_argument, 0, OPT_TIMESTAMP_FORMAT }, {"timestamp-format", required_argument, 0, OPT_TIMESTAMP_FORMAT },
{"list-devices", no_argument, 0, 'L' }, {"list-devices", no_argument, 0, 'L' },
{"log", no_argument, 0, 'l' }, {"log", no_argument, 0, 'l' },
{"log-file", required_argument, 0, OPT_LOG_FILE }, {"log-file", required_argument, 0, OPT_LOG_FILE },
{"log-strip", no_argument, 0, OPT_LOG_STRIP }, {"log-strip", no_argument, 0, OPT_LOG_STRIP },
{"socket", required_argument, 0, 'S' }, {"socket", required_argument, 0, 'S' },
{"map", required_argument, 0, 'm' }, {"map", required_argument, 0, 'm' },
{"color", required_argument, 0, 'c' }, {"color", required_argument, 0, 'c' },
{"hexadecimal", no_argument, 0, 'x' }, {"hexadecimal", no_argument, 0, 'x' },
{"response-wait", no_argument, 0, 'r' }, {"response-wait", no_argument, 0, 'r' },
{"response-timeout", required_argument, 0, OPT_RESPONSE_TIMEOUT }, {"response-timeout", required_argument, 0, OPT_RESPONSE_TIMEOUT },
{"rs-485", no_argument, 0, OPT_RS485 }, {"rs-485", no_argument, 0, OPT_RS485 },
{"rs-485-config", required_argument, 0, OPT_RS485_CONFIG }, {"rs-485-config", required_argument, 0, OPT_RS485_CONFIG },
{"alert", required_argument, 0, OPT_ALERT }, {"alert", required_argument, 0, OPT_ALERT },
{"version", no_argument, 0, 'v' }, {"version", no_argument, 0, 'v' },
{"help", no_argument, 0, 'h' }, {"help", no_argument, 0, 'h' },
{0, 0, 0, 0 } {"complete-sub-configs", no_argument, 0, OPT_COMPLETE_SUB_CONFIGS},
{0, 0, 0, 0 }
}; };
/* getopt_long stores the option index here */ /* getopt_long stores the option index here */
@ -418,6 +421,10 @@ void options_parse(int argc, char *argv[])
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case OPT_COMPLETE_SUB_CONFIGS:
option.complete_sub_configs = true;
break;
case '?': case '?':
/* getopt_long already printed an error message */ /* getopt_long already printed an error message */
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -434,6 +441,11 @@ void options_parse(int argc, char *argv[])
else if (optind < argc) else if (optind < argc)
option.tty_device = argv[optind++]; option.tty_device = argv[optind++];
if (option.complete_sub_configs)
{
return;
}
if (strlen(option.tty_device) == 0) if (strlen(option.tty_device) == 0)
{ {
tio_error_printf("Missing tty device or sub-configuration name"); tio_error_printf("Missing tty device or sub-configuration name");

View file

@ -66,6 +66,7 @@ struct option_t
int32_t rs485_delay_rts_before_send; int32_t rs485_delay_rts_before_send;
int32_t rs485_delay_rts_after_send; int32_t rs485_delay_rts_after_send;
enum alert_t alert; enum alert_t alert;
bool complete_sub_configs;
}; };
extern struct option_t option; extern struct option_t option;