9#include <ascii-chat/options/completions/fish.h>
10#include <ascii-chat/options/registry.h>
11#include <ascii-chat/options/enums.h>
12#include <ascii-chat/common.h>
18static void fish_escape_help(FILE *output,
const char *text) {
23 for (
const char *p = text; *p; p++) {
26 fprintf(output,
"'\\''");
27 }
else if (*p ==
'\n' || *p ==
'\t') {
36static void fish_write_option(FILE *output,
const option_descriptor_t *opt,
const char *condition) {
45 bool exclusive =
false;
48 if (meta->input_type == OPTION_INPUT_ENUM && meta->enum_values && meta->enum_values[0] != NULL) {
52 if (opt->short_name !=
'\0') {
53 fprintf(output,
"complete -c ascii-chat %s -s %c -x -a '%s' -d '", condition, opt->short_name,
54 meta->enum_values[0]);
55 fish_escape_help(output, opt->help_text);
56 fprintf(output,
"'\n");
59 for (
size_t i = 0; meta->enum_values[i] != NULL; i++) {
60 fprintf(output,
"complete -c ascii-chat %s -l %s -x -a '%s' -d '", condition, opt->long_name,
61 meta->enum_values[i]);
62 fish_escape_help(output, opt->help_text);
63 fprintf(output,
"'\n");
66 }
else if (meta->input_type == OPTION_INPUT_FILEPATH) {
69 }
else if (meta->examples && meta->examples[0] != NULL) {
73 if (opt->short_name !=
'\0') {
74 fprintf(output,
"complete -c ascii-chat %s -s %c -x -a '%s' -d '", condition, opt->short_name,
76 fish_escape_help(output, opt->help_text);
77 fprintf(output,
"'\n");
80 for (
size_t i = 0; meta->examples[i] != NULL; i++) {
81 fprintf(output,
"complete -c ascii-chat %s -l %s -x -a '%s' -d '", condition, opt->long_name,
83 fish_escape_help(output, opt->help_text);
84 fprintf(output,
"'\n");
87 }
else if (meta->input_type == OPTION_INPUT_NUMERIC) {
90 if (opt->short_name !=
'\0') {
91 fprintf(output,
"complete -c ascii-chat %s -s %c -x -a '%d' -d 'numeric (%d-%d)'\n", condition, opt->short_name,
92 meta->numeric_range.min, meta->numeric_range.min, meta->numeric_range.max);
94 fprintf(output,
"complete -c ascii-chat %s -l %s -x -a '%d' -d 'numeric (%d-%d)'\n", condition, opt->long_name,
95 meta->numeric_range.min, meta->numeric_range.min, meta->numeric_range.max);
96 if (meta->numeric_range.max > meta->numeric_range.min) {
97 int middle = (meta->numeric_range.min + meta->numeric_range.max) / 2;
98 fprintf(output,
"complete -c ascii-chat %s -l %s -x -a '%d' -d 'numeric (middle)'\n", condition, opt->long_name,
100 fprintf(output,
"complete -c ascii-chat %s -l %s -x -a '%d' -d 'numeric (max)'\n", condition, opt->long_name,
101 meta->numeric_range.max);
108 if (opt->short_name !=
'\0') {
110 fprintf(output,
"complete -c ascii-chat %s -s %c -x -d '", condition, opt->short_name);
111 fish_escape_help(output, opt->help_text);
112 fprintf(output,
"'\n");
114 fprintf(output,
"complete -c ascii-chat %s -s %c -d '", condition, opt->short_name);
115 fish_escape_help(output, opt->help_text);
116 fprintf(output,
"'\n");
120 fprintf(output,
"complete -c ascii-chat %s -l %s -x -d '", condition, opt->long_name);
121 fish_escape_help(output, opt->help_text);
122 fprintf(output,
"'\n");
124 fprintf(output,
"complete -c ascii-chat %s -l %s -d '", condition, opt->long_name);
125 fish_escape_help(output, opt->help_text);
126 fprintf(output,
"'\n");
132 return SET_ERRNO(ERROR_INVALID_PARAM,
"Output stream cannot be NULL");
136 "# Fish completion script for ascii-chat\n"
137 "# Generated from options registry - DO NOT EDIT MANUALLY\n"
139 "complete -c ascii-chat -f\n"
141 "function __fish_ascii_chat_using_mode\n"
142 " set -l cmd (commandline -opc)\n"
144 " if contains -- $arg server client mirror\n"
152 "function __fish_ascii_chat_mode_is\n"
153 " test (string match -q $argv[1] (command __fish_ascii_chat_using_mode))\n"
156 "function __fish_ascii_chat_no_mode\n"
157 " not __fish_ascii_chat_using_mode > /dev/null\n"
161 "complete -c ascii-chat -n __fish_ascii_chat_no_mode -a server -d 'Run a video chat server'\n"
162 "complete -c ascii-chat -n __fish_ascii_chat_no_mode -a client -d 'Connect to a video chat server'\n"
163 "complete -c ascii-chat -n __fish_ascii_chat_no_mode -a mirror -d 'View webcam locally without network'\n"
167 size_t binary_count = 0;
170 fprintf(output,
"# Binary-level options (same as 'ascii-chat --help')\n");
172 for (
size_t i = 0; i < binary_count; i++) {
173 fish_write_option(output, &binary_opts[i],
"");
175 SAFE_FREE(binary_opts);
177 fprintf(output,
"\n");
180 size_t server_count = 0;
183 fprintf(output,
"# Server options (same as 'ascii-chat server --help')\n");
185 for (
size_t i = 0; i < server_count; i++) {
186 fish_write_option(output, &server_opts[i],
"-n '__fish_seen_subcommand_from server'");
188 SAFE_FREE(server_opts);
190 fprintf(output,
"\n");
193 size_t client_count = 0;
196 fprintf(output,
"# Client options (same as 'ascii-chat client --help')\n");
198 for (
size_t i = 0; i < client_count; i++) {
199 fish_write_option(output, &client_opts[i],
"-n '__fish_seen_subcommand_from client'");
201 SAFE_FREE(client_opts);
203 fprintf(output,
"\n");
206 size_t mirror_count = 0;
209 fprintf(output,
"# Mirror options (same as 'ascii-chat mirror --help')\n");
211 for (
size_t i = 0; i < mirror_count; i++) {
212 fish_write_option(output, &mirror_opts[i],
"-n '__fish_seen_subcommand_from mirror'");
214 SAFE_FREE(mirror_opts);
216 fprintf(output,
"\n");
219 size_t discovery_svc_count = 0;
220 const option_descriptor_t *discovery_svc_opts =
223 fprintf(output,
"# Discovery-service options (same as 'ascii-chat discovery-service --help')\n");
224 if (discovery_svc_opts) {
225 for (
size_t i = 0; i < discovery_svc_count; i++) {
226 fish_write_option(output, &discovery_svc_opts[i],
"-n '__fish_seen_subcommand_from discovery-service'");
228 SAFE_FREE(discovery_svc_opts);
asciichat_error_t completions_generate_fish(FILE *output)
const option_descriptor_t * options_registry_get_for_display(asciichat_mode_t mode, bool for_binary_help, size_t *num_options)
const option_metadata_t * options_registry_get_metadata(const char *long_name)