ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
fish.c
Go to the documentation of this file.
1
7#include <string.h>
8#include <stdio.h>
12#include <ascii-chat/common.h>
13
18static void fish_escape_help(FILE *output, const char *text) {
19 if (!text) {
20 return;
21 }
22
23 for (const char *p = text; *p; p++) {
24 if (*p == '\'') {
25 // Escape single quotes by ending quote, adding escaped quote, starting quote again
26 fprintf(output, "'\\''");
27 } else if (*p == '\n' || *p == '\t') {
28 // Convert newlines and tabs to spaces
29 fprintf(output, " ");
30 } else {
31 fputc(*p, output);
32 }
33 }
34}
35
36static void fish_write_option(FILE *output, const option_descriptor_t *opt, const char *condition) {
37 if (!opt) {
38 return;
39 }
40
41 // Get completion metadata for this option
43
44 // Determine if we should exclude file completion
45 bool exclusive = false;
46
47 if (meta) {
48 if (meta->input_type == OPTION_INPUT_ENUM && meta->enum_values && meta->enum_values[0] != NULL) {
49 exclusive = true;
50 // Enum values as completions
51 // Output short option once with first value
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");
57 }
58 // Output long option with all values
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");
64 }
65 return;
66 } else if (meta->input_type == OPTION_INPUT_FILEPATH) {
67 // File paths use default fish file completion
68 exclusive = false;
69 } else if (meta->examples && meta->examples[0] != NULL) {
70 exclusive = true;
71 // Example values as completions (practical values, higher priority than calculated ranges)
72 // Output short option once with first example
73 if (opt->short_name != '\0') {
74 fprintf(output, "complete -c ascii-chat %s -s %c -x -a '%s' -d '", condition, opt->short_name,
75 meta->examples[0]);
76 fish_escape_help(output, opt->help_text);
77 fprintf(output, "'\n");
78 }
79 // Output long option with all examples
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,
82 meta->examples[i]);
83 fish_escape_help(output, opt->help_text);
84 fprintf(output, "'\n");
85 }
86 return;
87 } else if (meta->input_type == OPTION_INPUT_NUMERIC) {
88 exclusive = true;
89 // Numeric range - suggest min, middle, max values
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,
93 }
94 fprintf(output, "complete -c ascii-chat %s -l %s -x -a '%d' -d 'numeric (%d-%d)'\n", condition, opt->long_name,
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,
99 middle);
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);
102 }
103 return;
104 }
105 }
106
107 // Basic completion without values
108 if (opt->short_name != '\0') {
109 if (exclusive) {
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");
113 } else {
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");
117 }
118 }
119 if (exclusive) {
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");
123 } else {
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");
127 }
128}
129
131 if (!output) {
132 return SET_ERRNO(ERROR_INVALID_PARAM, "Output stream cannot be NULL");
133 }
134
135 fprintf(output,
136 "# Fish completion script for ascii-chat\n"
137 "# Generated from options registry - DO NOT EDIT MANUALLY\n"
138 "\n"
139 "complete -c ascii-chat -f\n"
140 "\n"
141 "function __fish_ascii_chat_using_mode\n"
142 " set -l cmd (commandline -opc)\n"
143 " for arg in $cmd\n"
144 " if contains -- $arg server client mirror\n"
145 " echo $arg\n"
146 " return 0\n"
147 " end\n"
148 " end\n"
149 " return 1\n"
150 "end\n"
151 "\n"
152 "function __fish_ascii_chat_mode_is\n"
153 " test (string match -q $argv[1] (command __fish_ascii_chat_using_mode))\n"
154 "end\n"
155 "\n"
156 "function __fish_ascii_chat_no_mode\n"
157 " not __fish_ascii_chat_using_mode > /dev/null\n"
158 "end\n"
159 "\n"
160 "# Modes\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"
164 "\n");
165
166 /* Binary options - use unified display API matching help system */
167 size_t binary_count = 0;
168 const option_descriptor_t *binary_opts = options_registry_get_for_display(MODE_DISCOVERY, true, &binary_count);
169
170 fprintf(output, "# Binary-level options (same as 'ascii-chat --help')\n");
171 if (binary_opts) {
172 for (size_t i = 0; i < binary_count; i++) {
173 fish_write_option(output, &binary_opts[i], "");
174 }
175 SAFE_FREE(binary_opts);
176 }
177 fprintf(output, "\n");
178
179 /* Server options - use unified display API matching help system */
180 size_t server_count = 0;
181 const option_descriptor_t *server_opts = options_registry_get_for_display(MODE_SERVER, false, &server_count);
182
183 fprintf(output, "# Server options (same as 'ascii-chat server --help')\n");
184 if (server_opts) {
185 for (size_t i = 0; i < server_count; i++) {
186 fish_write_option(output, &server_opts[i], "-n '__fish_seen_subcommand_from server'");
187 }
188 SAFE_FREE(server_opts);
189 }
190 fprintf(output, "\n");
191
192 /* Client options - use unified display API matching help system */
193 size_t client_count = 0;
194 const option_descriptor_t *client_opts = options_registry_get_for_display(MODE_CLIENT, false, &client_count);
195
196 fprintf(output, "# Client options (same as 'ascii-chat client --help')\n");
197 if (client_opts) {
198 for (size_t i = 0; i < client_count; i++) {
199 fish_write_option(output, &client_opts[i], "-n '__fish_seen_subcommand_from client'");
200 }
201 SAFE_FREE(client_opts);
202 }
203 fprintf(output, "\n");
204
205 /* Mirror options - use unified display API matching help system */
206 size_t mirror_count = 0;
207 const option_descriptor_t *mirror_opts = options_registry_get_for_display(MODE_MIRROR, false, &mirror_count);
208
209 fprintf(output, "# Mirror options (same as 'ascii-chat mirror --help')\n");
210 if (mirror_opts) {
211 for (size_t i = 0; i < mirror_count; i++) {
212 fish_write_option(output, &mirror_opts[i], "-n '__fish_seen_subcommand_from mirror'");
213 }
214 SAFE_FREE(mirror_opts);
215 }
216 fprintf(output, "\n");
217
218 /* Discovery-service options */
219 size_t discovery_svc_count = 0;
220 const option_descriptor_t *discovery_svc_opts =
221 options_registry_get_for_display(MODE_DISCOVERY_SERVICE, false, &discovery_svc_count);
222
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'");
227 }
228 SAFE_FREE(discovery_svc_opts);
229 }
230
231 return ASCIICHAT_OK;
232}
@ OPTION_INPUT_NUMERIC
Numeric value with optional min/max/step.
Definition builder.h:179
@ OPTION_INPUT_FILEPATH
File path completion.
Definition builder.h:181
@ OPTION_INPUT_ENUM
Choose from fixed set of enum values.
Definition builder.h:178
⚙️ Common definitions, error codes, macros, and types shared throughout the application
Option enum value definitions - single source of truth.
asciichat_error_t completions_generate_fish(FILE *output)
Generate fish completion script.
Definition fish.c:130
Fish shell completion generator.
#define SAFE_FREE(ptr)
Definition common.h:376
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_INVALID_PARAM
@ MODE_CLIENT
Client mode - network client options.
@ MODE_DISCOVERY_SERVICE
Discovery server mode - session management and WebRTC signaling.
@ MODE_SERVER
Server mode - network server options.
@ MODE_MIRROR
Mirror mode - local webcam viewing (no network)
@ MODE_DISCOVERY
Discovery mode - participant that can dynamically become host.
const option_descriptor_t * options_registry_get_for_display(asciichat_mode_t mode, bool for_binary_help, size_t *num_options)
Get options for help/completions display with unified filtering.
Definition public_api.c:324
const option_metadata_t * options_registry_get_metadata(const char *long_name)
Get complete metadata for an option.
Definition public_api.c:370
Central registry of all command-line options with mode applicability.
Option descriptor.
Definition builder.h:241
const char * help_text
Description for –help.
Definition builder.h:251
const char * long_name
Long option name (e.g., "port")
Definition builder.h:243
char short_name
Short option char (e.g., 'p', or '\0' if none)
Definition builder.h:244
Metadata for shell completion generation.
Definition builder.h:192
int max
Maximum value (or 0 if no limit)
Definition builder.h:203
int min
Minimum value (or 0 if no limit)
Definition builder.h:202
option_input_type_t input_type
What kind of input this option expects.
Definition builder.h:214
const char ** examples
Example values or command invocations (null-terminated array)
Definition builder.h:208
const char ** enum_values
Enum value strings (null-terminated, e.g., {"auto", "none", "16", "256", "truecolor",...
Definition builder.h:195
struct option_metadata_t::@19 numeric_range