9#include <ascii-chat/options/completions/zsh.h>
10#include <ascii-chat/options/registry.h>
11#include <ascii-chat/common.h>
17static void zsh_escape_help(FILE *output,
const char *text) {
22 for (
const char *p = text; *p; p++) {
27 fprintf(output,
"\\%c", *p);
31 fprintf(output,
"'\\''");
47static void zsh_write_option(FILE *output,
const option_descriptor_t *opt) {
56 char completion_spec[512] =
"";
58 if (meta->input_type == OPTION_INPUT_ENUM && meta->enum_values && meta->enum_values[0] != NULL) {
61 pos +=
safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
":(");
62 for (
size_t i = 0; meta->enum_values[i] != NULL && pos <
sizeof(completion_spec) - 1; i++) {
64 pos +=
safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
" ");
65 pos +=
safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
"%s", meta->enum_values[i]);
67 safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
")");
68 }
else if (meta->input_type == OPTION_INPUT_FILEPATH) {
70 SAFE_STRNCPY(completion_spec,
":_files",
sizeof(completion_spec));
71 }
else if (meta->examples && meta->examples[0] != NULL) {
74 pos +=
safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
":(");
75 for (
size_t i = 0; meta->examples[i] != NULL && pos <
sizeof(completion_spec) - 1; i++) {
77 pos +=
safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
" ");
78 pos +=
safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
"%s", meta->examples[i]);
80 safe_snprintf(completion_spec + pos,
sizeof(completion_spec) - pos,
")");
81 }
else if (meta->input_type == OPTION_INPUT_NUMERIC) {
83 if (meta->numeric_range.min > 0 || meta->numeric_range.max > 0) {
84 safe_snprintf(completion_spec,
sizeof(completion_spec),
":(numeric %d-%d)", meta->numeric_range.min,
85 meta->numeric_range.max);
87 SAFE_STRNCPY(completion_spec,
":(numeric)",
sizeof(completion_spec));
93 if (opt->short_name !=
'\0') {
94 fprintf(output,
" '-%c[", opt->short_name);
95 zsh_escape_help(output, opt->help_text);
96 fprintf(output,
"]%s' \\\n", completion_spec);
100 fprintf(output,
" '--%s[", opt->long_name);
101 zsh_escape_help(output, opt->help_text);
102 fprintf(output,
"]%s' \\\n", completion_spec);
107 return SET_ERRNO(ERROR_INVALID_PARAM,
"Output stream cannot be NULL");
110 fprintf(output,
"#compdef _ascii_chat ascii-chat\n"
112 "#compdef _ascii_chat build/bin/ascii-chat ./build/bin/ascii-chat\n"
114 "# Zsh completion script for ascii-chat\n"
115 "# Generated from options registry - DO NOT EDIT MANUALLY\n"
118 " local curcontext=\"$curcontext\" state line\n"
119 " _arguments -C \\\n");
122 size_t binary_count = 0;
126 for (
size_t i = 0; i < binary_count; i++) {
127 zsh_write_option(output, &binary_opts[i]);
129 SAFE_FREE(binary_opts);
132 fprintf(output,
" '1:mode:(server client mirror discovery-service)' \\\n"
133 " '*::mode args:_ascii_chat_subcommand'\n"
136 "_ascii_chat_subcommand() {\n"
137 " case $line[1] in\n"
142 size_t server_count = 0;
146 for (
size_t i = 0; i < server_count; i++) {
147 zsh_write_option(output, &server_opts[i]);
149 SAFE_FREE(server_opts);
152 fprintf(output,
" && return 0\n"
158 size_t client_count = 0;
162 for (
size_t i = 0; i < client_count; i++) {
163 zsh_write_option(output, &client_opts[i]);
165 SAFE_FREE(client_opts);
168 fprintf(output,
" && return 0\n"
174 size_t mirror_count = 0;
178 for (
size_t i = 0; i < mirror_count; i++) {
179 zsh_write_option(output, &mirror_opts[i]);
181 SAFE_FREE(mirror_opts);
184 fprintf(output,
" && return 0\n"
186 " discovery-service)\n"
190 size_t discovery_svc_count = 0;
191 const option_descriptor_t *discovery_svc_opts =
194 if (discovery_svc_opts) {
195 for (
size_t i = 0; i < discovery_svc_count; i++) {
196 zsh_write_option(output, &discovery_svc_opts[i]);
198 SAFE_FREE(discovery_svc_opts);
201 fprintf(output,
" && return 0\n"
206 "_ascii_chat \"$@\"\n");
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)
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Safe formatted string printing to buffer.
asciichat_error_t completions_generate_zsh(FILE *output)