ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
zsh.h File Reference

Zsh shell completion generator. More...

Go to the source code of this file.

Functions

asciichat_error_t completions_generate_zsh (FILE *output)
 Generate zsh completion script.

Detailed Description

Zsh shell completion generator.

Definition in file zsh.h.

Function Documentation

◆ completions_generate_zsh()

asciichat_error_t completions_generate_zsh ( FILE * output)

Generate zsh completion script.

Definition at line 142 of file zsh.c.

142 {
143 if (!output) {
144 return SET_ERRNO(ERROR_INVALID_PARAM, "Output stream cannot be NULL");
145 }
146
147 // Before a mode, expose the complete registry; after a mode, use its own options.
148 size_t binary_count = 0;
149 const option_descriptor_t *binary_opts = options_registry_get_for_display(MODE_DISCOVERY, true, &binary_count);
150
151 fprintf(output, "# Zsh completion script for ascii-chat\n"
152 "# Generated from options registry - DO NOT EDIT MANUALLY\n"
153 "\n"
154 "# Configure completion for ascii-chat\n"
155 "# Use only _complete (no corrections or approximate matching)\n"
156 "zstyle ':completion:*:ascii-chat:*' completer _complete\n"
157 "\n"
158 "# Device index completion helpers\n"
159 "_ascii_chat_webcam_indices() {\n"
160 " local -a indices\n"
161 " local output\n"
162 " output=$(\"${words[1]}\" --list-webcams 2>/dev/null) || return\n"
163 " while IFS= read -r line; do\n"
164 " [[ \"$line\" =~ ^[[:space:]]*([0-9]+)[[:space:]]+(.+)$ ]] && \\\n"
165 " indices+=(\"${match[1]}:${match[2]}\")\n"
166 " done <<< \"$output\"\n"
167 " _describe 'webcam' indices\n"
168 "}\n"
169 "\n"
170 "_ascii_chat_microphone_indices() {\n"
171 " local -a indices\n"
172 " local output\n"
173 " output=$(\"${words[1]}\" --list-microphones 2>/dev/null) || return\n"
174 " while IFS= read -r line; do\n"
175 " [[ \"$line\" =~ ^[[:space:]]*([0-9-]+)[[:space:]]+(.+)$ ]] && \\\n"
176 " indices+=(\"${match[1]}:${match[2]}\")\n"
177 " done <<< \"$output\"\n"
178 " _describe 'microphone' indices\n"
179 "}\n"
180 "\n"
181 "_ascii_chat_speakers_indices() {\n"
182 " local -a indices\n"
183 " local output\n"
184 " output=$(\"${words[1]}\" --list-speakers 2>/dev/null) || return\n"
185 " while IFS= read -r line; do\n"
186 " [[ \"$line\" =~ ^[[:space:]]*([0-9-]+)[[:space:]]+(.+)$ ]] && \\\n"
187 " indices+=(\"${match[1]}:${match[2]}\")\n"
188 " done <<< \"$output\"\n"
189 " _describe 'speakers' indices\n"
190 "}\n"
191 "\n"
192 "_ascii_chat_binary_grouped() {\n"
193 " local curcontext=$curcontext\n"
194 " local -a context line state_descr args\n"
195 " local state\n"
196 " local -A opt_args\n\n");
197
198 /* Write binary-level options in grouped format */
199 if (binary_opts) {
200 zsh_write_combined_args(output, binary_opts, binary_count, true);
201 }
202
203 fprintf(output, "}\n\n_ascii_chat() {\n"
204 " local i mode=''\n"
205 " for (( i=2; i<CURRENT; ++i )); do\n"
206 " case $words[i] in\n"
207 " --) break ;;\n"
208 " --*=*) continue ;;\n");
209 // Skip required option values so a file called 'mirror' is not a mode.
210 for (size_t i = 0; i < binary_count; ++i) {
211 const option_descriptor_t *opt = &binary_opts[i];
212 if (opt->type == OPTION_TYPE_ACTION || opt->type == OPTION_TYPE_BOOL || opt->optional_arg)
213 continue;
214 fprintf(output, " --%s", opt->long_name);
215 if (opt->short_name)
216 fprintf(output, "|-%c", opt->short_name);
217 fprintf(output, ") (( ++i )) ;;\n");
218 }
219 fprintf(output, " server|client|mirror|discovery-service|acds|mcp-server)\n"
220 " mode=$words[i]\n"
221 " words=(\"$words[1]\" \"${(@)words[i+1,-1]}\")\n"
222 " (( CURRENT -= i - 1 ))\n"
223 " break ;;\n"
224 " esac\n"
225 " done\n"
226 " case $mode in\n"
227 " # Server-like modes\n"
228 " server)\n"
229 " _ascii_chat_server\n"
230 " return\n"
231 " ;;\n"
232 " discovery-service|acds)\n"
233 " _ascii_chat_discovery_service\n"
234 " return\n"
235 " ;;\n"
236 "\n"
237 " mcp-server)\n"
238 " _ascii_chat_mcp_server\n"
239 " return\n"
240 " ;;\n"
241 " # Client-like modes\n"
242 " client)\n"
243 " _ascii_chat_client\n"
244 " return\n"
245 " ;;\n"
246 " mirror)\n"
247 " _ascii_chat_mirror\n"
248 " return\n"
249 " ;;\n"
250 " *) _ascii_chat_binary_grouped ;;\n"
251 " esac\n"
252 "}\n\n"
253 "_ascii_chat_modes() {\n"
254 " local -a server_modes client_modes\n"
255 " server_modes=(\n");
256
257 /* Generate server-like modes from registry */
258 size_t mode_server_count = 0;
259 const mode_descriptor_t *mode_server_descs = get_modes_by_group("server-like", &mode_server_count);
260 if (mode_server_descs) {
261 for (size_t i = 0; i < mode_server_count; i++) {
262 fprintf(output, " '%s:%s'\n", mode_server_descs[i].name, mode_server_descs[i].description);
263 }
264 SAFE_FREE(mode_server_descs);
265 }
266
267 fprintf(output, " )\n"
268 " client_modes=(\n");
269
270 /* Generate client-like modes from registry (exclude discovery since it's the default mode) */
271 size_t mode_client_count = 0;
272 const mode_descriptor_t *mode_client_descs = get_modes_by_group("client-like", &mode_client_count);
273 if (mode_client_descs) {
274 for (size_t i = 0; i < mode_client_count; i++) {
275 /* Skip discovery mode - it's the default when no mode is specified */
276 if (strcmp(mode_client_descs[i].name, "discovery") == 0) {
277 continue;
278 }
279 fprintf(output, " '%s:%s'\n", mode_client_descs[i].name, mode_client_descs[i].description);
280 }
281 SAFE_FREE(mode_client_descs);
282 }
283
284 fprintf(output, " )\n"
285 " _describe -t server-modes 'server-like modes' server_modes\n"
286 " _describe -t client-modes 'client-like modes' client_modes\n"
287 "}\n\n"
288 "# Server-like modes: handle incoming connections and stream management\n"
289 "_ascii_chat_server() {\n"
290 " local curcontext=$curcontext\n"
291 " local -a context line state_descr args\n"
292 " local state\n"
293 " local -A opt_args\n\n");
294
295 /* Server options - grouped by category */
296 size_t server_count = 0;
297 const option_descriptor_t *server_opts = options_registry_get_for_display(MODE_SERVER, false, &server_count);
298
299 if (server_opts) {
300 zsh_write_combined_args(output, server_opts, server_count, false);
301 SAFE_FREE(server_opts);
302 }
303
304 fprintf(output, "}\n"
305 "\n"
306 "_ascii_chat_discovery_service() {\n"
307 " local curcontext=$curcontext\n"
308 " local -a context line state_descr args\n"
309 " local state\n"
310 " local -A opt_args\n\n");
311
312 /* Discovery-service options - grouped by category */
313 size_t discovery_svc_count = 0;
314 const option_descriptor_t *discovery_svc_opts =
315 options_registry_get_for_display(MODE_DISCOVERY_SERVICE, false, &discovery_svc_count);
316
317 if (discovery_svc_opts) {
318 zsh_write_combined_args(output, discovery_svc_opts, discovery_svc_count, false);
319 SAFE_FREE(discovery_svc_opts);
320 }
321
322 fprintf(output, "}\n"
323 "\n"
324 "# Client-like modes: connect to servers or render local media\n"
325 "_ascii_chat_client() {\n"
326 " local curcontext=$curcontext\n"
327 " local -a context line state_descr args\n"
328 " local state\n"
329 " local -A opt_args\n\n");
330
331 /* Client options - grouped by category */
332 size_t client_count = 0;
333 const option_descriptor_t *client_opts = options_registry_get_for_display(MODE_CLIENT, false, &client_count);
334
335 if (client_opts) {
336 zsh_write_combined_args(output, client_opts, client_count, false);
337 SAFE_FREE(client_opts);
338 }
339
340 fprintf(output, "}\n"
341 "\n"
342 "_ascii_chat_mirror() {\n"
343 " local curcontext=$curcontext\n"
344 " local -a context line state_descr args\n"
345 " local state\n"
346 " local -A opt_args\n\n");
347
348 /* Mirror options - grouped by category */
349 size_t mirror_count = 0;
350 const option_descriptor_t *mirror_opts = options_registry_get_for_display(MODE_MIRROR, false, &mirror_count);
351
352 if (mirror_opts) {
353 zsh_write_combined_args(output, mirror_opts, mirror_count, false);
354 SAFE_FREE(mirror_opts);
355 }
356
357 fprintf(output, "}\n"
358 "\n"
359 "# Register completion functions (must come after definitions)\n"
360 "compdef _ascii_chat ascii-chat\n"
361 "compdef _ascii_chat 'build/bin/ascii-chat'\n");
362
363 fprintf(output, "_ascii_chat_mcp_server() {\n"
364 " local curcontext=$curcontext\n"
365 " local -a context line state_descr args\n"
366 " local state\n"
367 " local -A opt_args\n\n");
368 size_t mcp_count = 0;
369 const option_descriptor_t *mcp_opts = options_registry_get_for_display(MODE_MCP_SERVER, false, &mcp_count);
370 if (mcp_opts) {
371 zsh_write_combined_args(output, mcp_opts, mcp_count, false);
372 SAFE_FREE(mcp_opts);
373 }
374 fprintf(output, "}\n\n");
375
376 SAFE_FREE(binary_opts);
377
378 return ASCIICHAT_OK;
379}
#define SET_ERRNO(code,...)
@ OPTION_TYPE_ACTION
Action that executes and may exit (–list-webcams, etc.).
Definition builder.h:172
@ OPTION_TYPE_BOOL
Boolean flag (–flag, no value).
Definition builder.h:167
#define SAFE_FREE(ptr)
Definition common.h:377
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
@ MODE_CLIENT
Client mode - network client options.
Definition options.h:921
@ MODE_MCP_SERVER
Model Context Protocol rendering server.
Definition options.h:925
@ MODE_DISCOVERY_SERVICE
Discovery server mode - session management and WebRTC signaling.
Definition options.h:923
@ MODE_SERVER
Server mode - network server options.
Definition options.h:920
@ MODE_MIRROR
Mirror mode - local webcam viewing (no network).
Definition options.h:922
@ MODE_DISCOVERY
Discovery mode - participant that can dynamically become host.
Definition options.h:924
const mode_descriptor_t * get_modes_by_group(const char *group, size_t *out_count)
Get all mode descriptors grouped by category.
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:279
Metadata for a mode.
Definition main.c:410
The complete registry entry for one command-line/configuration option.
Definition builder.h:249
const char * long_name
Long option name (e.g., "port").
Definition builder.h:251
char short_name
Short option char (e.g., 'p', or '\0' if none).
Definition builder.h:252
option_type_t type
Value type.
Definition builder.h:255
bool optional_arg
If true, argument is optional (for callbacks like –verbose).
Definition builder.h:283