[READ-ONLY] Mirror of https://github.com/bombshell-dev/tab. shell autocompletions for javascript CLIs
4

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'main' of https://github.com/bombshell-dev/tab

AmirSa12 (Dec 19, 2024, 11:41 PM +0330) ab1040ce e3be5d3b

+104
+104
shadcn.cac.ts
··· 1 + import fs from "fs/promises"; 2 + import cac from "cac"; 3 + import { 4 + Callback, 5 + Completion, 6 + flagMap, 7 + Positional, 8 + positionalMap, 9 + } from "./shared"; 10 + import path from "path"; 11 + import tab from "./cac"; 12 + 13 + const cli = cac("shadcn"); // Using 'shadcn' as the CLI tool name 14 + 15 + // Global options 16 + cli 17 + .option("-c, --cwd [cwd]", `[string] the working directory. defaults to the current directory.`) 18 + .option("-h, --help", `display help for command`); 19 + 20 + // Init command 21 + cli 22 + .command("init", "initialize your project and install dependencies") 23 + .option("-d, --defaults", `[boolean] use default values i.e new-york, zinc, and css variables`, { default: false }) 24 + .option("-f, --force", `[boolean] force overwrite of existing components.json`, { default: false }) 25 + .option("-y, --yes", `[boolean] skip confirmation prompt`, { default: false }) 26 + .action((options) => { 27 + console.log(`Initializing project with options:`, options); 28 + }); 29 + 30 + // Add command 31 + cli 32 + .command("add [...components]", "add a component to your project") 33 + .option("-y, --yes", `[boolean] skip confirmation prompt`, { default: false }) 34 + .option("-o, --overwrite", `[boolean] overwrite existing files`, { default: false }) 35 + .option("-a, --all", `[boolean] add all available components`, { default: false }) 36 + .option("-p, --path [path]", `[string] the path to add the component to`) 37 + .action((components, options) => { 38 + console.log(`Adding components:`, components, `with options:`, options); 39 + }); 40 + 41 + // Build positional completions for each command using command.args 42 + for (const c of [cli.globalCommand, ...cli.commands]) { 43 + // Handle options 44 + for (const o of [...cli.globalCommand.options, ...c.options]) { 45 + const optionKey = `${c.name} ${o.name}`; 46 + 47 + if (o.rawName.includes("--cwd <cwd>")) { 48 + // Completion for --cwd (common working directories) 49 + flagMap.set(optionKey, async (previousArgs, toComplete) => { 50 + return [ 51 + { action: "./apps/www", description: "Default app directory" }, 52 + { action: "./apps/admin", description: "Admin app directory" }, 53 + ].filter((comp) => comp.action.startsWith(toComplete)); 54 + }); 55 + } 56 + 57 + if (o.rawName.includes("--defaults")) { 58 + // Completion for --defaults (show info for default setup) 59 + flagMap.set(optionKey, async (previousArgs, toComplete) => { 60 + return [{ action: "true", description: "Use default values for setup" }]; 61 + }); 62 + } 63 + 64 + if (o.rawName.includes("--path <path>")) { 65 + // Completion for --path (common component paths) 66 + flagMap.set(optionKey, async (previousArgs, toComplete) => { 67 + return [ 68 + { action: "src/components", description: "Main components directory" }, 69 + { action: "src/ui", description: "UI components directory" }, 70 + ].filter((comp) => comp.action.startsWith(toComplete)); 71 + }); 72 + } 73 + } 74 + 75 + // Handle positional arguments 76 + if (c.name === "add" && c.args && c.args.length > 0) { 77 + const componentChoices = [ 78 + "accordion", "alert", "alert-dialog", "aspect-ratio", "avatar", 79 + "badge", "button", "calendar", "card", "checkbox" 80 + ]; 81 + const positionals = c.args.map((arg) => ({ 82 + required: arg.required, 83 + variadic: arg.variadic, 84 + value: arg.value, 85 + completion: async (previousArgs, toComplete) => { 86 + // if (arg.value === "root") { 87 + return componentChoices 88 + // TODO: a bug here that toComplete is equal to "add" which then makes filter not work, we should omit toComplete and add it to previous args if the endsWithSpace is true 89 + // .filter((comp) => comp.startsWith(toComplete)) 90 + .map((comp) => ({ action: comp, description: `Add ${comp} component` })); 91 + // } 92 + // return []; 93 + }, 94 + })); 95 + 96 + positionalMap.set(c.name, positionals); 97 + } 98 + } 99 + 100 + // Initialize tab completion 101 + tab(cli); 102 + 103 + cli.parse(); 104 +