mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-29 12:31:52 -04:00
* feat(completion): generate-completion close #3083 * feat: better error message * test: generate-completion * feat(completion): add powershell * chore(deps): update @pnpm/tabtab to 0.3.0 * switch to provided type declarations * fix typings * update tests * update bundle scripts * refactor: remove unnecessary `??` * refactor: replace a type def with provided types * chore(deps): update @pnpm/tabtab to 0.4.0 * feat(cli): rename completion command * chore(deps): update @pnpm/tabtab to 0.4.1 * refactor: use tabtab's new features * fix: pass shell * chore(deps): update @pnpm/tabtab to 0.5.0 * chore(deps): update @pnpm/tabtab to 0.5.1 * fix: remove unused import * refactor: move completion to plugins * feat: remove `{install,uninstall}-completion` Just `pnpm completion` is enough * test: fix * refactor: direct import * refactor: move tests to next to the lib * refactor: merge 2 packages into 1 * fix: update changeset and remove install-completion
86 lines
2.9 KiB
TypeScript
86 lines
2.9 KiB
TypeScript
import { type CompletionItem } from '@pnpm/tabtab'
|
|
import { type CompletionFunc } from '@pnpm/command'
|
|
import { findWorkspaceDir } from '@pnpm/find-workspace-dir'
|
|
import { findWorkspacePackages } from '@pnpm/workspace.find-packages'
|
|
import { getOptionCompletions } from './getOptionType'
|
|
import { optionTypesToCompletions } from './optionTypesToCompletions'
|
|
|
|
export async function complete (
|
|
ctx: {
|
|
cliOptionsTypesByCommandName: Record<string, () => Record<string, unknown>>
|
|
completionByCommandName: Record<string, CompletionFunc>
|
|
initialCompletion: () => CompletionItem[]
|
|
shorthandsByCommandName: Record<string, Record<string, string | string[]>>
|
|
universalOptionsTypes: Record<string, unknown>
|
|
universalShorthands: Record<string, string>
|
|
},
|
|
input: {
|
|
params: string[]
|
|
cmd: string | null
|
|
currentTypedWordType: 'option' | 'value' | null
|
|
lastOption: string | null
|
|
options: Record<string, unknown>
|
|
}
|
|
): Promise<CompletionItem[]> {
|
|
if (input.options.version) return []
|
|
const optionTypes = {
|
|
...ctx.universalOptionsTypes,
|
|
...((input.cmd && ctx.cliOptionsTypesByCommandName[input.cmd]?.()) ?? {}),
|
|
}
|
|
|
|
// Autocompleting option values
|
|
if (input.currentTypedWordType !== 'option') {
|
|
if (input.lastOption === '--filter') {
|
|
const workspaceDir = await findWorkspaceDir(process.cwd()) ?? process.cwd()
|
|
const allProjects = await findWorkspacePackages(workspaceDir, {
|
|
supportedArchitectures: {
|
|
os: ['current'],
|
|
cpu: ['current'],
|
|
libc: ['current'],
|
|
},
|
|
})
|
|
return allProjects
|
|
.map(({ manifest }) => ({ name: manifest.name }))
|
|
.filter((item): item is CompletionItem => !!item.name)
|
|
} else if (input.lastOption) {
|
|
const optionCompletions = getOptionCompletions(
|
|
optionTypes as any, // eslint-disable-line
|
|
{
|
|
...ctx.universalShorthands,
|
|
...(input.cmd ? ctx.shorthandsByCommandName[input.cmd] : {}),
|
|
},
|
|
input.lastOption
|
|
)
|
|
if (optionCompletions !== undefined) {
|
|
return optionCompletions.map((name) => ({ name }))
|
|
}
|
|
}
|
|
}
|
|
let completions: CompletionItem[] = []
|
|
if (input.currentTypedWordType !== 'option') {
|
|
if (!input.cmd || input.currentTypedWordType === 'value' && !ctx.completionByCommandName[input.cmd]) {
|
|
completions = ctx.initialCompletion()
|
|
} else if (ctx.completionByCommandName[input.cmd]) {
|
|
try {
|
|
completions = await ctx.completionByCommandName[input.cmd](input.options, input.params)
|
|
} catch (err) {
|
|
// Ignore
|
|
}
|
|
}
|
|
}
|
|
if (input.currentTypedWordType === 'value') {
|
|
return completions
|
|
}
|
|
if (!input.cmd) {
|
|
return [
|
|
...completions,
|
|
...optionTypesToCompletions(optionTypes),
|
|
{ name: '--version' },
|
|
]
|
|
}
|
|
return [
|
|
...completions,
|
|
...optionTypesToCompletions(optionTypes as any), // eslint-disable-line
|
|
]
|
|
}
|