From 72ae630c3fc9d6d5653eae6a95c55da6aa5f2f4a Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Fri, 30 Jan 2026 07:10:13 +0000 Subject: [PATCH] Add generators: code, completion, and docs generators --- src/generators/completion-generator.ts | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/generators/completion-generator.ts diff --git a/src/generators/completion-generator.ts b/src/generators/completion-generator.ts new file mode 100644 index 0000000..60aee6e --- /dev/null +++ b/src/generators/completion-generator.ts @@ -0,0 +1,89 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import Handlebars from 'handlebars'; +import type { CLISpec, ShellType } from '../types/spec.js'; + +const TEMPLATE_DIR = path.resolve(process.cwd(), 'src', 'templates'); + +function getTemplatePath(shell: ShellType): string { + return path.join(TEMPLATE_DIR, `completion-${shell}.handlebars`); +} + +function getTemplateContent(shell: ShellType): string { + const templatePath = getTemplatePath(shell); + if (!fs.existsSync(templatePath)) { + throw new Error(`Completion template not found: ${templatePath}`); + } + return fs.readFileSync(templatePath, 'utf-8'); +} + +function compileTemplate(content: string): Handlebars.TemplateDelegate { + Handlebars.registerHelper('escape', function (str: string) { + return str.replace(/'/g, "'\\''").replace(/\n/g, ' '); + }); + + Handlebars.registerHelper('defaultValue', function (value: unknown) { + if (value === undefined || value === null) return ''; + return String(value); + }); + + return Handlebars.compile(content, { noEscape: true }); +} + +export interface CompletionResult { + success: boolean; + script?: string; + error?: string; +} + +export function generateCompletion(spec: CLISpec, shell: ShellType): CompletionResult { + try { + const templateContent = getTemplateContent(shell); + const template = compileTemplate(templateContent); + const script = template({ spec }); + return { success: true, script }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error during completion generation', + }; + } +} + +export function getCompletionFileName(spec: CLISpec, shell: ShellType): string { + const baseName = spec.bin || spec.name; + const extensions: Record = { + 'bash': 'bash', + 'zsh': 'zsh', + 'fish': 'fish', + }; + return `_${baseName}.${extensions[shell]}`; +} + +export function getInstallInstructions(spec: CLISpec, shell: ShellType): string { + const fileName = getCompletionFileName(spec, shell); + + switch (shell) { + case 'bash': + return `# Add to ~/.bashrc or /etc/bash_completion.d/ +source ${fileName} +# Or for user-specific installation: +echo "source $(pwd)/${fileName}" >> ~/.bashrc`; + + case 'zsh': + return `# Add to ~/.zshrc or create file in ~/.zsh/completion/ +mkdir -p ~/.zsh/completion +cp ${fileName} ~/.zsh/completion/ +echo "fpath=(~/.zsh/completion \\$$fpath)" >> ~/.zshrc +autoload -U compinit +compinit`; + + case 'fish': + return `# Add to ~/.config/fish/completions/ +mkdir -p ~/.config/fish/completions/ +cp ${fileName} ~/.config/fish/completions/`; + + default: + return `Unknown shell: ${shell}`; + } +}