Skip to content

Commit 81e36cf

Browse files
committed
updates
1 parent 8877baa commit 81e36cf

File tree

11 files changed

+210
-30
lines changed

11 files changed

+210
-30
lines changed

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,18 @@ For permanent setup in zsh, add this to your `~/.zshrc`:
1616

1717
```bash
1818
# Add to ~/.zshrc for permanent autocompletions (same can be done for other shells)
19-
source <(nuxi complete zsh)
19+
source <(nuxt complete zsh)
2020
```
2121

2222
### Package Manager Integration
2323

24-
`@bomb.sh/tab` integrates with [package managers](https://github.com/bombshell-dev/tab?tab=readme-ov-file#package-manager-completions). Autocompletions work when running nuxi directly:
24+
`@bomb.sh/tab` integrates with [package managers](https://github.com/bombshell-dev/tab?tab=readme-ov-file#package-manager-completions). Autocompletions work when running `nuxt` directly within a Nuxt project:
2525

2626
```bash
27-
npx nuxi <Tab>
28-
npm exec nuxi <Tab>
29-
pnpm nuxi <Tab>
30-
yarn nuxi <Tab>
31-
bun nuxi <Tab>
27+
pnpm nuxt <Tab>
28+
npm run nuxt <Tab>
29+
yarn nuxt <Tab>
30+
bun nuxt <Tab>
3231
```
3332

3433
For package manager autocompletions, you should install [tab's package manager completions](https://github.com/bombshell-dev/tab?tab=readme-ov-file#package-manager-completions) separately.

packages/create-nuxt/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"citty": "^0.1.6"
3434
},
3535
"devDependencies": {
36+
"@bomb.sh/tab": "^0.0.6",
3637
"@types/node": "^22.18.10",
3738
"rollup": "^4.52.4",
3839
"rollup-plugin-visualizer": "^6.0.4",

packages/create-nuxt/src/main.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { defineCommand } from 'citty'
22
import { provider } from 'std-env'
33

44
import init from '../../nuxi/src/commands/init'
5+
import { setupInitCompletions } from '../../nuxi/src/completions-init'
56
import { setupGlobalConsole } from '../../nuxi/src/utils/console'
67
import { checkEngines } from '../../nuxi/src/utils/engines'
78
import { logger } from '../../nuxi/src/utils/logger'
@@ -15,6 +16,11 @@ export const main = defineCommand({
1516
},
1617
args: init.args,
1718
async setup(ctx) {
19+
const isCompletionRequest = ctx.args._?.[0] === 'complete'
20+
if (isCompletionRequest) {
21+
return
22+
}
23+
1824
setupGlobalConsole({ dev: false })
1925

2026
// Check Node.js version and CLI updates in background
@@ -25,3 +31,5 @@ export const main = defineCommand({
2531
await init.run?.(ctx)
2632
},
2733
})
34+
35+
await setupInitCompletions(main)

packages/nuxi/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,18 @@
2929
},
3030
"scripts": {
3131
"dev:prepare": "unbuild --stub",
32-
"build": "unbuild",
32+
"build": "pnpm generate:completions-data && unbuild",
3333
"build:stub": "unbuild --stub",
3434
"dev": "node ./bin/nuxi.mjs dev ./playground",
3535
"dev:bun": "bun --bun ./bin/nuxi.mjs dev ./playground",
36+
"generate:completions-data": "tsx ./scripts/generate-completions-data.ts",
3637
"nuxi": "node ./bin/nuxi.mjs",
3738
"nuxi-bun": "bun --bun ./bin/nuxi.mjs",
3839
"prepack": "unbuild",
3940
"test:dist": "node ./bin/nuxi.mjs info ./playground"
4041
},
4142
"devDependencies": {
42-
"@bomb.sh/tab": "^0.0.5",
43+
"@bomb.sh/tab": "^0.0.6",
4344
"@nuxt/kit": "^4.1.3",
4445
"@nuxt/schema": "^4.1.3",
4546
"@nuxt/test-utils": "^3.19.2",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/** generate completion data from nitropack and Nuxt starter repo */
2+
3+
import { writeFile } from 'node:fs/promises'
4+
import { fileURLToPath } from 'node:url'
5+
import { dirname, resolve } from 'node:path'
6+
// @ts-expect-error: internal nitropack file
7+
import allPresets from '../node_modules/nitropack/dist/presets/_all.gen.mjs'
8+
9+
const __dirname = dirname(fileURLToPath(import.meta.url))
10+
11+
interface PresetMeta {
12+
_meta?: { name: string }
13+
}
14+
15+
async function generateCompletionData() {
16+
const data: {
17+
nitroPresets: string[]
18+
templates: string[]
19+
} = {
20+
nitroPresets: [],
21+
templates: [],
22+
}
23+
24+
data.nitroPresets = (allPresets as PresetMeta[])
25+
.map(preset => preset._meta?.name)
26+
.filter((name): name is string => Boolean(name))
27+
.filter(name => !['base-worker', 'nitro-dev', 'nitro-prerender'].includes(name))
28+
.filter((name, index, array) => array.indexOf(name) === index)
29+
.sort()
30+
31+
const response = await fetch(
32+
'https://api.github.com/repos/nuxt/starter/contents/templates?ref=templates'
33+
)
34+
35+
if (!response.ok) {
36+
throw new Error(`GitHub API error: ${response.status}`)
37+
}
38+
39+
const files = await response.json() as Array<{ name: string; type: string }>
40+
41+
const templateEntries = files
42+
.filter(file => {
43+
if (file.type === 'dir') return true
44+
if (file.type === 'file' && file.name.endsWith('.json') && file.name !== 'content.json') {
45+
return true
46+
}
47+
return false
48+
})
49+
.map(file => file.name.replace('.json', ''))
50+
51+
data.templates = Array.from(new Set(templateEntries))
52+
.filter(name => name !== 'community')
53+
.sort()
54+
55+
const outputPath = resolve(__dirname, '../src/completions-data.ts')
56+
const content = `/** Auto-generated file */
57+
58+
export const nitroPresets = ${JSON.stringify(data.nitroPresets, null, 2)} as const
59+
60+
export const templates = ${JSON.stringify(data.templates, null, 2)} as const
61+
`
62+
63+
await writeFile(outputPath, content, 'utf-8')
64+
}
65+
66+
generateCompletionData().catch((error) => {
67+
console.error('Failed to generate completion data:', error)
68+
process.exit(1)
69+
})
70+
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/** Auto-generated file */
2+
3+
export const nitroPresets = [
4+
"alwaysdata",
5+
"aws-amplify",
6+
"aws-lambda",
7+
"azure-functions",
8+
"azure-swa",
9+
"bun",
10+
"cleavr",
11+
"cli",
12+
"cloudflare-dev",
13+
"cloudflare-durable",
14+
"cloudflare-module",
15+
"cloudflare-module-legacy",
16+
"cloudflare-pages",
17+
"cloudflare-pages-static",
18+
"cloudflare-worker",
19+
"deno-deploy",
20+
"deno-server",
21+
"deno-server-legacy",
22+
"digital-ocean",
23+
"edgio",
24+
"firebase",
25+
"firebase-app-hosting",
26+
"flight-control",
27+
"genezio",
28+
"github-pages",
29+
"gitlab-pages",
30+
"heroku",
31+
"iis-handler",
32+
"iis-node",
33+
"koyeb",
34+
"netlify",
35+
"netlify-builder",
36+
"netlify-edge",
37+
"netlify-legacy",
38+
"netlify-static",
39+
"node-cluster",
40+
"node-listener",
41+
"node-server",
42+
"platform-sh",
43+
"render-com",
44+
"service-worker",
45+
"static",
46+
"stormkit",
47+
"vercel",
48+
"vercel-edge",
49+
"vercel-static",
50+
"winterjs",
51+
"zeabur",
52+
"zeabur-static",
53+
"zerops",
54+
"zerops-static"
55+
] as const
56+
57+
export const templates = [
58+
"doc-driven",
59+
"hub",
60+
"layer",
61+
"module",
62+
"module-devtools",
63+
"ui",
64+
"ui-vue",
65+
"v2-bridge",
66+
"v3",
67+
"v4",
68+
"v4-compat"
69+
] as const
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { ArgsDef, CommandDef } from 'citty'
2+
import tab from '@bomb.sh/tab/citty'
3+
import { templates } from './completions-data'
4+
5+
export async function setupInitCompletions<T extends ArgsDef = ArgsDef>(command: CommandDef<T>) {
6+
const completion = await tab(command)
7+
8+
const templateOption = completion.options?.get('template')
9+
if (templateOption) {
10+
templateOption.handler = (complete) => {
11+
for (const template of templates) {
12+
complete(template, '')
13+
}
14+
}
15+
}
16+
17+
const logLevelOption = completion.options?.get('logLevel')
18+
if (logLevelOption) {
19+
logLevelOption.handler = (complete) => {
20+
complete('silent', 'No logs')
21+
complete('info', 'Standard logging')
22+
complete('verbose', 'Detailed logging')
23+
}
24+
}
25+
26+
return completion
27+
}
28+

packages/nuxi/src/completions.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ArgsDef, CommandDef } from 'citty'
22
import tab from '@bomb.sh/tab/citty'
3+
import { nitroPresets, templates } from './completions-data'
34

45
export async function initCompletions<T extends ArgsDef = ArgsDef>(command: CommandDef<T>) {
56
const completion = await tab(command)
@@ -30,16 +31,9 @@ export async function initCompletions<T extends ArgsDef = ArgsDef>(command: Comm
3031
const presetOption = buildCommand.options.get('preset')
3132
if (presetOption) {
3233
presetOption.handler = (complete) => {
33-
complete('node-server', 'Node.js server')
34-
complete('static', 'Static hosting')
35-
complete('cloudflare-pages', 'Cloudflare Pages')
36-
complete('vercel', 'Vercel')
37-
complete('netlify', 'Netlify')
38-
complete('aws-lambda', 'AWS Lambda')
39-
complete('azure', 'Azure')
40-
complete('firebase', 'Firebase')
41-
complete('deno-deploy', 'Deno Deploy')
42-
complete('bun', 'Bun runtime')
34+
for (const preset of nitroPresets) {
35+
complete(preset, '')
36+
}
4337
}
4438
}
4539
}
@@ -49,8 +43,9 @@ export async function initCompletions<T extends ArgsDef = ArgsDef>(command: Comm
4943
const templateOption = initCommand.options.get('template')
5044
if (templateOption) {
5145
templateOption.handler = (complete) => {
52-
complete('v3', 'Nuxt 3 template')
53-
complete('v4', 'Nuxt 4 template')
46+
for (const template of templates) {
47+
complete(template, '')
48+
}
5449
}
5550
}
5651
}
@@ -65,7 +60,7 @@ export async function initCompletions<T extends ArgsDef = ArgsDef>(command: Comm
6560
}
6661
}
6762

68-
const logLevelCommands = ['dev', 'build', 'generate', 'preview', 'prepare']
63+
const logLevelCommands = ['dev', 'build', 'generate', 'preview', 'prepare', 'init']
6964
for (const cmdName of logLevelCommands) {
7065
const cmd = completion.commands.get(cmdName)
7166
if (cmd) {

packages/nuxt-cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"prepack": "unbuild"
3434
},
3535
"dependencies": {
36+
"@bomb.sh/tab": "^0.0.6",
3637
"c12": "^3.3.0",
3738
"citty": "^0.1.6",
3839
"clipboardy": "^5.0.0",

packages/nuxt-cli/src/run.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { fileURLToPath } from 'node:url'
44
import { runCommand as _runCommand, runMain as _runMain } from 'citty'
55

66
import { commands } from '../../nuxi/src/commands'
7+
import { initCompletions } from '../../nuxi/src/completions'
78
import { main } from './main'
89

910
globalThis.__nuxt_cli__ = globalThis.__nuxt_cli__ || {
@@ -17,7 +18,10 @@ globalThis.__nuxt_cli__ = globalThis.__nuxt_cli__ || {
1718
),
1819
}
1920

20-
export const runMain = () => _runMain(main)
21+
export const runMain = async () => {
22+
await initCompletions(main)
23+
return _runMain(main)
24+
}
2125

2226
export async function runCommand(
2327
name: string,

0 commit comments

Comments
 (0)