-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.ts
73 lines (63 loc) · 2.48 KB
/
search.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import {Command, loadHelpClass, toConfiguredId, toStandardizedId, ux} from '@oclif/core'
import ansiEscapes from 'ansi-escapes'
import autocomplete from 'inquirer-autocomplete-standalone'
import readline from 'node:readline'
export default class Search extends Command {
public static description = 'Once you select a command, hit enter and it will show the help for that command.'
public static summary = 'Search for a command.'
public async run(): Promise<unknown> {
this.log(
ux.colorize(
'cyan',
`Use ${ux.colorize('bold', '↑')} and ${ux.colorize('bold', '↓')} keys or type to search for a command.\nPress ${ux.colorize('bold', 'ENTER')} to view help. Press ${ux.colorize('bold', 'ESC')} to exit.\n`,
),
)
const commandChoices = this.config.commands
.filter((c) => !c.hidden && !c.aliases.includes(c.id))
.sort((a, b) => a.id.localeCompare(b.id))
.map((c) => {
const name = toConfiguredId(c.id, this.config)
return {
description: c.summary,
name,
value: name,
}
})
const pageSize = Math.floor(process.stdout.rows < 20 ? process.stdout.rows / 2 : 10)
const commandPromise = autocomplete<string>({
emptyText: 'Nothing found!',
message: 'Search for a command',
pageSize,
async source(input) {
return input ? commandChoices.filter((c) => c.name.includes(input)) : commandChoices
},
})
function cancel() {
commandPromise.cancel()
// erase the list of commands
process.stdout.write(ansiEscapes.eraseLines(pageSize + 3))
}
readline.emitKeypressEvents(process.stdin)
process.stdin.setRawMode(true)
process.stdin.on('keypress', (_, key) => {
if (key.name === 'escape') cancel()
if (key.name === 'c' && key.ctrl) cancel()
})
const command = await commandPromise
.catch((error) => {
if (error.message === 'Prompt was canceled') return
throw error
})
.then((result) => result)
if (!command) return
const Help = await loadHelpClass(this.config)
const help = new Help(this.config, this.config.pjson.oclif.helpOptions ?? this.config.pjson.helpOptions)
return help.showHelp([toStandardizedId(command, this.config)])
}
}