ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
completions.c File Reference

Implementation of shell completion generation from options registry. More...

Go to the source code of this file.

Functions

asciichat_error_t completions_generate_bash (FILE *output)
 
asciichat_error_t completions_generate_fish (FILE *output)
 
asciichat_error_t completions_generate_zsh (FILE *output)
 
asciichat_error_t completions_generate_powershell (FILE *output)
 
asciichat_error_t completions_generate_for_shell (completion_format_t format, FILE *output)
 Generate shell completions and write to output stream.
 
const char * completions_get_shell_name (completion_format_t format)
 Get human-readable shell name for format.
 
completion_format_t completions_parse_shell_name (const char *shell_name)
 Parse shell name string to completion format.
 
option_descriptor_t * completions_collect_all_modes_unique (size_t *count)
 Collect options from all modes with deduplication.
 

Detailed Description

Implementation of shell completion generation from options registry.

Definition in file completions.c.

Function Documentation

◆ completions_collect_all_modes_unique()

option_descriptor_t * completions_collect_all_modes_unique ( size_t *  count)

Collect options from all modes with deduplication.

Iterates through all completion modes (MODE_DISCOVERY, MODE_SERVER, MODE_CLIENT, MODE_MIRROR, MODE_DISCOVERY_SERVICE) and collects unique options by long_name. Useful for generators that need to show completions for options across multiple modes.

Parameters
[out]countPointer to receive the count of unique options
Returns
Dynamically allocated array of option_descriptor_t, must be freed by caller. Returns NULL if no options found.
Note
The caller must free the returned pointer with SAFE_FREE()

Definition at line 96 of file completions.c.

96 {
97 if (!count) {
98 return NULL;
99 }
100
101 option_descriptor_t *combined_opts = NULL;
102 size_t combined_count = 0;
103
104 /* All completion modes to iterate through */
106 const size_t modes_len = sizeof(modes) / sizeof(modes[0]);
107
108 for (size_t m = 0; m < modes_len; m++) {
109 size_t mode_count = 0;
110 const option_descriptor_t *mode_opts = options_registry_get_for_mode(modes[m], &mode_count);
111 if (mode_opts) {
112 /* Collect unique options by long_name */
113 for (size_t i = 0; i < mode_count; i++) {
114 bool already_has = false;
115 for (size_t j = 0; j < combined_count; j++) {
116 if (strcmp(combined_opts[j].long_name, mode_opts[i].long_name) == 0) {
117 already_has = true;
118 break;
119 }
120 }
121 if (!already_has) {
122 combined_count++;
124 combined_opts, combined_count * sizeof(option_descriptor_t), option_descriptor_t *);
125 if (temp) {
126 combined_opts = temp;
127 combined_opts[combined_count - 1] = mode_opts[i];
128 }
129 }
130 }
131 SAFE_FREE(mode_opts);
132 }
133 }
134
135 *count = combined_count;
136 return combined_opts;
137}
#define SAFE_REALLOC(ptr, size, cast)
Definition common.h:284
#define SAFE_FREE(ptr)
Definition common.h:376
asciichat_mode_t
Mode type for options parsing.
@ 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_mode(asciichat_mode_t mode, size_t *num_options)
Get all options for a specific mode.
Definition public_api.c:218
Option descriptor.
Definition builder.h:241

References MODE_CLIENT, MODE_DISCOVERY, MODE_DISCOVERY_SERVICE, MODE_MIRROR, MODE_SERVER, options_registry_get_for_mode(), SAFE_FREE, and SAFE_REALLOC.

◆ completions_generate_bash()

asciichat_error_t completions_generate_bash ( FILE *  output)

Definition at line 367 of file bash.c.

367 {
368 if (!output) {
369 return SET_ERRNO(ERROR_INVALID_PARAM, "Output stream cannot be NULL");
370 }
371
372 bash_write_header(output);
373 asciichat_error_t err = bash_write_all_options(output);
374 if (err != ASCIICHAT_OK) {
375 return err;
376 }
377 bash_write_completion_logic(output);
378 bash_write_footer(output);
379
380 return ASCIICHAT_OK;
381}
#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

Referenced by completions_generate_for_shell().

◆ completions_generate_fish()

asciichat_error_t completions_generate_fish ( FILE *  output)

Definition at line 130 of file fish.c.

130 {
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}
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

References ASCIICHAT_OK, ERROR_INVALID_PARAM, MODE_CLIENT, MODE_DISCOVERY, MODE_DISCOVERY_SERVICE, MODE_MIRROR, MODE_SERVER, options_registry_get_for_display(), SAFE_FREE, and SET_ERRNO.

Referenced by completions_generate_for_shell().

◆ completions_generate_for_shell()

asciichat_error_t completions_generate_for_shell ( completion_format_t  format,
FILE *  output 
)

Generate shell completions and write to output stream.

Generates a complete shell completion script for the specified shell format by extracting option metadata from the centralized registry.

Parameters
formatShell format to generate completions for
outputFILE stream to write completion script to (e.g., stdout)
Returns
ASCIICHAT_OK on success, error code on failure

Definition at line 20 of file completions.c.

20 {
21 if (!output) {
22 return SET_ERRNO(ERROR_INVALID_PARAM, "Output stream cannot be NULL");
23 }
24
25 switch (format) {
27 return completions_generate_bash(output);
29 return completions_generate_fish(output);
31 return completions_generate_zsh(output);
34 default:
35 return SET_ERRNO(ERROR_INVALID_PARAM, "Unknown completion format: %d", format);
36 }
37}
asciichat_error_t completions_generate_bash(FILE *output)
Definition bash.c:367
asciichat_error_t completions_generate_powershell(FILE *output)
Definition powershell.c:130
asciichat_error_t completions_generate_fish(FILE *output)
Definition fish.c:130
asciichat_error_t completions_generate_zsh(FILE *output)
Definition zsh.c:210
@ COMPLETION_FORMAT_BASH
Definition completions.h:67
@ COMPLETION_FORMAT_ZSH
Definition completions.h:69
@ COMPLETION_FORMAT_POWERSHELL
Definition completions.h:70
@ COMPLETION_FORMAT_FISH
Definition completions.h:68

References COMPLETION_FORMAT_BASH, COMPLETION_FORMAT_FISH, COMPLETION_FORMAT_POWERSHELL, COMPLETION_FORMAT_ZSH, completions_generate_bash(), completions_generate_fish(), completions_generate_powershell(), completions_generate_zsh(), ERROR_INVALID_PARAM, and SET_ERRNO.

Referenced by action_completions().

◆ completions_generate_powershell()

asciichat_error_t completions_generate_powershell ( FILE *  output)

Definition at line 130 of file powershell.c.

130 {
131 if (!output) {
132 return SET_ERRNO(ERROR_INVALID_PARAM, "Output stream cannot be NULL");
133 }
134
135 fprintf(output, "# PowerShell completion script for ascii-chat\n"
136 "# Generated from options registry - DO NOT EDIT MANUALLY\n"
137 "# Usage: ascii-chat --completions powershell | Out-String | Invoke-Expression\n"
138 "\n"
139 "$script:AsciiChatCompleter = {\n"
140 " param($wordToComplete, $commandAst, $cursorPosition)\n"
141 "\n"
142 " $words = @($commandAst.CommandElements | ForEach-Object { $_.Value })\n"
143 " $mode = $null\n"
144 "\n"
145 " foreach ($word in $words) {\n"
146 " if ($word -in @('server', 'client', 'mirror')) {\n"
147 " $mode = $word\n"
148 " break\n"
149 " }\n"
150 " }\n"
151 "\n"
152 " $binaryOptions = @(\n");
153
154 /* Binary options - use unified display API matching help system */
155 size_t binary_count = 0;
156 const option_descriptor_t *binary_opts = options_registry_get_for_display(MODE_DISCOVERY, true, &binary_count);
157
158 if (binary_opts) {
159 for (size_t i = 0; i < binary_count; i++) {
160 ps_write_option(output, &binary_opts[i]);
161 }
162 SAFE_FREE(binary_opts);
163 }
164
165 fprintf(output, " )\n\n $serverOptions = @(\n");
166
167 /* Server options - use unified display API matching help system */
168 size_t server_count = 0;
169 const option_descriptor_t *server_opts = options_registry_get_for_display(MODE_SERVER, false, &server_count);
170
171 if (server_opts) {
172 for (size_t i = 0; i < server_count; i++) {
173 ps_write_option(output, &server_opts[i]);
174 }
175 SAFE_FREE(server_opts);
176 }
177
178 fprintf(output, " )\n\n $clientOptions = @(\n");
179
180 /* Client options - use unified display API matching help system */
181 size_t client_count = 0;
182 const option_descriptor_t *client_opts = options_registry_get_for_display(MODE_CLIENT, false, &client_count);
183
184 if (client_opts) {
185 for (size_t i = 0; i < client_count; i++) {
186 ps_write_option(output, &client_opts[i]);
187 }
188 SAFE_FREE(client_opts);
189 }
190
191 fprintf(output, " )\n\n $mirrorOptions = @(\n");
192
193 /* Mirror options - use unified display API matching help system */
194 size_t mirror_count = 0;
195 const option_descriptor_t *mirror_opts = options_registry_get_for_display(MODE_MIRROR, false, &mirror_count);
196
197 if (mirror_opts) {
198 for (size_t i = 0; i < mirror_count; i++) {
199 ps_write_option(output, &mirror_opts[i]);
200 }
201 SAFE_FREE(mirror_opts);
202 }
203
204 fprintf(output, " )\n\n $discoverySvcOptions = @(\n");
205
206 /* Discovery-service options */
207 size_t discovery_svc_count = 0;
208 const option_descriptor_t *discovery_svc_opts =
209 options_registry_get_for_display(MODE_DISCOVERY_SERVICE, false, &discovery_svc_count);
210
211 if (discovery_svc_opts) {
212 for (size_t i = 0; i < discovery_svc_count; i++) {
213 ps_write_option(output, &discovery_svc_opts[i]);
214 }
215 SAFE_FREE(discovery_svc_opts);
216 }
217
218 fprintf(output,
219 " )\n"
220 "\n"
221 " $options = $binaryOptions\n"
222 " \n"
223 " if ($mode -eq 'server') {\n"
224 " $options += $serverOptions\n"
225 " } elseif ($mode -eq 'client') {\n"
226 " $options += $clientOptions\n"
227 " } elseif ($mode -eq 'mirror') {\n"
228 " $options += $mirrorOptions\n"
229 " } elseif ($mode -eq 'discovery-service') {\n"
230 " $options += $discoverySvcOptions\n"
231 " }\n"
232 "\n"
233 " if (-not $mode -and -not $wordToComplete.StartsWith('-')) {\n"
234 " @('server', 'client', 'mirror', 'discovery-service') | Where-Object { $_ -like \"$wordToComplete*\" } | "
235 "ForEach-Object {\n"
236 " [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', \"Mode: $_\")\n"
237 " }\n"
238 " } else {\n"
239 " $options | Where-Object { $_.Name -like \"$wordToComplete*\" } | ForEach-Object {\n"
240 " if ($_.Values) {\n"
241 " $_.Values | ForEach-Object {\n"
242 " [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_.Description)\n"
243 " }\n"
244 " } else {\n"
245 " [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', "
246 "$_.Description)\n"
247 " }\n"
248 " }\n"
249 " }\n"
250 "}\n"
251 "\n"
252 "Register-ArgumentCompleter -CommandName ascii-chat -ScriptBlock $script:AsciiChatCompleter\n");
253
254 return ASCIICHAT_OK;
255}

References ASCIICHAT_OK, ERROR_INVALID_PARAM, MODE_CLIENT, MODE_DISCOVERY, MODE_DISCOVERY_SERVICE, MODE_MIRROR, MODE_SERVER, options_registry_get_for_display(), SAFE_FREE, and SET_ERRNO.

Referenced by completions_generate_for_shell().

◆ completions_generate_zsh()

asciichat_error_t completions_generate_zsh ( FILE *  output)

Definition at line 210 of file zsh.c.

210 {
211 if (!output) {
212 return SET_ERRNO(ERROR_INVALID_PARAM, "Output stream cannot be NULL");
213 }
214
215 /* Load binary-level and discovery options for binary-level completion.
216 * Binary-level completion (options before mode name like --color-mode) uses
217 * _arguments with -n -S flags to establish proper zsh completion context.
218 * Without _arguments, completion functions fail with "can only be called from
219 * completion function" error, causing zsh to display "corrections (errors: N)"
220 * messages. The -n flag disables defaults and -S disables short option
221 * processing, allowing safe context establishment. */
222 size_t binary_count = 0;
223 const option_descriptor_t *binary_opts = options_registry_get_for_display(MODE_DISCOVERY, true, &binary_count);
224
225 size_t discovery_count = 0;
226 const option_descriptor_t *discovery_opts = options_registry_get_for_display(MODE_DISCOVERY, false, &discovery_count);
227
228 fprintf(output, "# Zsh completion script for ascii-chat\n"
229 "# Generated from options registry - DO NOT EDIT MANUALLY\n"
230 "\n"
231 "# Configure completion for ascii-chat\n"
232 "# Use only _complete (no corrections or approximate matching)\n"
233 "zstyle ':completion:*:ascii-chat:*' completer _complete\n"
234 "\n"
235 "# Device index completion helpers\n"
236 "_ascii_chat_webcam_indices() {\n"
237 " local -a indices\n"
238 " local output\n"
239 " output=$(\"${words[1]}\" --list-webcams 2>/dev/null) || return\n"
240 " while IFS= read -r line; do\n"
241 " [[ \"$line\" =~ ^[[:space:]]*([0-9]+)[[:space:]]+(.+)$ ]] && \\\n"
242 " indices+=(\"${match[1]}:${match[2]}\")\n"
243 " done <<< \"$output\"\n"
244 " _describe 'webcam' indices\n"
245 "}\n"
246 "\n"
247 "_ascii_chat_microphone_indices() {\n"
248 " local -a indices\n"
249 " local output\n"
250 " output=$(\"${words[1]}\" --list-microphones 2>/dev/null) || return\n"
251 " while IFS= read -r line; do\n"
252 " [[ \"$line\" =~ ^[[:space:]]*([0-9-]+)[[:space:]]+(.+)$ ]] && \\\n"
253 " indices+=(\"${match[1]}:${match[2]}\")\n"
254 " done <<< \"$output\"\n"
255 " _describe 'microphone' indices\n"
256 "}\n"
257 "\n"
258 "_ascii_chat_speakers_indices() {\n"
259 " local -a indices\n"
260 " local output\n"
261 " output=$(\"${words[1]}\" --list-speakers 2>/dev/null) || return\n"
262 " while IFS= read -r line; do\n"
263 " [[ \"$line\" =~ ^[[:space:]]*([0-9-]+)[[:space:]]+(.+)$ ]] && \\\n"
264 " indices+=(\"${match[1]}:${match[2]}\")\n"
265 " done <<< \"$output\"\n"
266 " _describe 'speakers' indices\n"
267 "}\n"
268 "\n"
269 "_ascii_chat_binary() {\n"
270 " local -a binary_opts=(\n");
271
272 /* Add discovery options to binary-level completion */
273 if (discovery_opts) {
274 for (size_t i = 0; i < discovery_count; i++) {
275 fprintf(output, " '--%s:", discovery_opts[i].long_name);
276 zsh_escape_desc(output, discovery_opts[i].help_text);
277 fprintf(output, "'\n");
278 }
279 }
280
281 fprintf(output, " )\n"
282 " _values 'option' \"${binary_opts[@]}\"\n"
283 "}\n"
284 "\n"
285 "_ascii_chat_binary_grouped() {\n"
286 " local curcontext=$curcontext\n"
287 " local -a context line state state_descr args\n"
288 " local -A opt_args\n\n");
289
290 /* Write binary-level options in grouped format */
291 if (binary_opts) {
292 zsh_write_combined_args(output, binary_opts, binary_count);
293 }
294
295 fprintf(output, "}\n"
296 "\n"
297 "_ascii_chat() {\n"
298 " if [[ ${words[2]} == -* ]]; then\n"
299 " # Binary-level options: show both binary and discovery mode options\n"
300 " # (since discovery is the default mode that runs at binary level)\n"
301 " _ascii_chat_binary_grouped\n"
302 " _ascii_chat_discovery\n"
303 " return\n"
304 " fi\n"
305 "\n"
306 " # Mode routing: check words[2] to determine which mode function to call\n"
307 " case $words[2] in\n"
308 " # Server-like modes\n"
309 " server)\n"
310 " _ascii_chat_server\n"
311 " return\n"
312 " ;;\n"
313 " discovery-service)\n"
314 " _ascii_chat_discovery_service\n"
315 " return\n"
316 " ;;\n"
317 "\n"
318 " # Client-like modes\n"
319 " client)\n"
320 " _ascii_chat_client\n"
321 " return\n"
322 " ;;\n"
323 " mirror)\n"
324 " _ascii_chat_mirror\n"
325 " return\n"
326 " ;;\n"
327 " # Default/unknown input - show mode selection only if truly empty, otherwise discovery\n"
328 " *)\n"
329 " # If words[2] is empty AND we're at position 2, show mode selection\n"
330 " # Otherwise (even for partial input like 'disc'), use discovery mode (the default)\n"
331 " if [[ -z \"${words[2]}\" && $CURRENT -eq 2 ]]; then\n"
332 " # Completing the mode name itself - show available modes\n"
333 " local -a server_modes client_modes\n"
334 " server_modes=(\n");
335
336 /* Generate server-like modes from registry */
337 size_t mode_server_count = 0;
338 const mode_descriptor_t *mode_server_descs = get_modes_by_group("server-like", &mode_server_count);
339 if (mode_server_descs) {
340 for (size_t i = 0; i < mode_server_count; i++) {
341 fprintf(output, " '%s:%s'\n", mode_server_descs[i].name, mode_server_descs[i].description);
342 }
343 SAFE_FREE(mode_server_descs);
344 }
345
346 fprintf(output, " )\n"
347 " client_modes=(\n");
348
349 /* Generate client-like modes from registry (exclude discovery since it's the default mode) */
350 size_t mode_client_count = 0;
351 const mode_descriptor_t *mode_client_descs = get_modes_by_group("client-like", &mode_client_count);
352 if (mode_client_descs) {
353 for (size_t i = 0; i < mode_client_count; i++) {
354 /* Skip discovery mode - it's the default when no mode is specified */
355 if (strcmp(mode_client_descs[i].name, "discovery") == 0) {
356 continue;
357 }
358 fprintf(output, " '%s:%s'\n", mode_client_descs[i].name, mode_client_descs[i].description);
359 }
360 SAFE_FREE(mode_client_descs);
361 }
362
363 fprintf(output, " )\n"
364 " _describe -t server-modes 'server-like modes' server_modes\n"
365 " _describe -t client-modes 'client-like modes' client_modes\n"
366 " else\n"
367 " # Default mode (discovery) - complete its options\n"
368 " _ascii_chat_discovery\n"
369 " fi\n"
370 " ;;\n"
371 " esac\n"
372 "}\n"
373 "\n"
374 "# Server-like modes: handle incoming connections and stream management\n"
375 "_ascii_chat_server() {\n"
376 " local curcontext=$curcontext\n"
377 " local -a context line state state_descr args\n"
378 " local -A opt_args\n\n");
379
380 /* Server options - grouped by category */
381 size_t server_count = 0;
382 const option_descriptor_t *server_opts = options_registry_get_for_display(MODE_SERVER, false, &server_count);
383
384 if (server_opts) {
385 zsh_write_combined_args(output, server_opts, server_count);
386 SAFE_FREE(server_opts);
387 }
388
389 fprintf(output, "}\n"
390 "\n"
391 "_ascii_chat_discovery_service() {\n"
392 " local curcontext=$curcontext\n"
393 " local -a context line state state_descr args\n"
394 " local -A opt_args\n\n");
395
396 /* Discovery-service options - grouped by category */
397 size_t discovery_svc_count = 0;
398 const option_descriptor_t *discovery_svc_opts =
399 options_registry_get_for_display(MODE_DISCOVERY_SERVICE, false, &discovery_svc_count);
400
401 if (discovery_svc_opts) {
402 zsh_write_combined_args(output, discovery_svc_opts, discovery_svc_count);
403 SAFE_FREE(discovery_svc_opts);
404 }
405
406 fprintf(output, "}\n"
407 "\n"
408 "# Client-like modes: connect to servers or render local media\n"
409 "_ascii_chat_client() {\n"
410 " local curcontext=$curcontext\n"
411 " local -a context line state state_descr args\n"
412 " local -A opt_args\n\n");
413
414 /* Client options - grouped by category */
415 size_t client_count = 0;
416 const option_descriptor_t *client_opts = options_registry_get_for_display(MODE_CLIENT, false, &client_count);
417
418 if (client_opts) {
419 zsh_write_combined_args(output, client_opts, client_count);
420 SAFE_FREE(client_opts);
421 }
422
423 fprintf(output, "}\n"
424 "\n"
425 "_ascii_chat_mirror() {\n"
426 " local curcontext=$curcontext\n"
427 " local -a context line state state_descr args\n"
428 " local -A opt_args\n\n");
429
430 /* Mirror options - grouped by category */
431 size_t mirror_count = 0;
432 const option_descriptor_t *mirror_opts = options_registry_get_for_display(MODE_MIRROR, false, &mirror_count);
433
434 if (mirror_opts) {
435 zsh_write_combined_args(output, mirror_opts, mirror_count);
436 SAFE_FREE(mirror_opts);
437 }
438
439 fprintf(output, "}\n"
440 "\n"
441 "# Discovery mode: find sessions via discovery service (default mode when no mode specified)\n"
442 "_ascii_chat_discovery() {\n"
443 " local curcontext=$curcontext\n"
444 " local -a context line state state_descr args\n"
445 " local -A opt_args\n\n");
446
447 /* Discovery options - grouped by category (reuse already-loaded options) */
448 if (discovery_opts) {
449 zsh_write_combined_args(output, discovery_opts, discovery_count);
450 }
451
452 fprintf(output, "}\n"
453 "\n"
454 "# Register completion functions (must come after definitions)\n"
455 "compdef _ascii_chat ascii-chat\n"
456 "compdef _ascii_chat 'build/bin/ascii-chat'\n");
457
458 SAFE_FREE(binary_opts);
459 SAFE_FREE(discovery_opts);
460
461 return ASCIICHAT_OK;
462}
const mode_descriptor_t * get_modes_by_group(const char *group, size_t *out_count)
Get all mode descriptors grouped by category.
Metadata for a mode.
Definition main.c:366

References ASCIICHAT_OK, ERROR_INVALID_PARAM, get_modes_by_group(), MODE_CLIENT, MODE_DISCOVERY, MODE_DISCOVERY_SERVICE, MODE_MIRROR, MODE_SERVER, options_registry_get_for_display(), SAFE_FREE, and SET_ERRNO.

Referenced by completions_generate_for_shell().

◆ completions_get_shell_name()

const char * completions_get_shell_name ( completion_format_t  format)

Get human-readable shell name for format.

Parameters
formatCompletion format
Returns
Shell name string (e.g., "bash", "fish"), or "unknown" if invalid

Definition at line 39 of file completions.c.

39 {
40 switch (format) {
42 return "bash";
44 return "fish";
46 return "zsh";
48 return "powershell";
49 default:
50 return "unknown";
51 }
52}

References COMPLETION_FORMAT_BASH, COMPLETION_FORMAT_FISH, COMPLETION_FORMAT_POWERSHELL, and COMPLETION_FORMAT_ZSH.

Referenced by action_completions().

◆ completions_parse_shell_name()

completion_format_t completions_parse_shell_name ( const char *  shell_name)

Parse shell name string to completion format.

Converts a shell name (e.g., "bash", "fish") to the corresponding completion format enum. Case-insensitive.

Parameters
shell_nameShell name string (e.g., "bash", "fish", "zsh")
Returns
Completion format, or COMPLETION_FORMAT_UNKNOWN if not recognized

Definition at line 54 of file completions.c.

54 {
55 if (!shell_name) {
57 }
58
59 /* Convert to lowercase for case-insensitive matching */
60 char lower[32] = {0};
61 size_t len = strlen(shell_name);
62 if (len >= sizeof(lower)) {
64 }
65
66 for (size_t i = 0; i < len; i++) {
67 lower[i] = tolower((unsigned char)shell_name[i]);
68 }
69
70 if (strcmp(lower, "bash") == 0) {
72 } else if (strcmp(lower, "fish") == 0) {
74 } else if (strcmp(lower, "zsh") == 0) {
76 } else if (strcmp(lower, "powershell") == 0 || strcmp(lower, "ps") == 0) {
78 }
79
81}
@ COMPLETION_FORMAT_UNKNOWN
Definition completions.h:71

References COMPLETION_FORMAT_BASH, COMPLETION_FORMAT_FISH, COMPLETION_FORMAT_POWERSHELL, COMPLETION_FORMAT_UNKNOWN, and COMPLETION_FORMAT_ZSH.

Referenced by action_completions().