Skip to content

Commit 97065ce

Browse files
authored
feat(cli): add shortcuts (#2353)
1 parent af4bb52 commit 97065ce

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/node/cli.ts

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createLogger } from 'vite'
44
import { build, createServer, serve } from '.'
55
import { init } from './init/init'
66
import { version } from '../../package.json'
7+
import { bindShortcuts } from './shortcuts'
78

89
const argv: any = minimist(process.argv.slice(2))
910

@@ -33,6 +34,7 @@ if (!command || command === 'dev') {
3334
await server.listen()
3435
logVersion(server.config.logger)
3536
server.printUrls()
37+
bindShortcuts(server)
3638
}
3739
createDevServer().catch((err) => {
3840
createLogger().error(

src/node/shortcuts.ts

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import colors from 'picocolors'
2+
import type { ViteDevServer } from 'vite'
3+
4+
export type CLIShortcut = {
5+
key: string
6+
description: string
7+
action(server: ViteDevServer): void | Promise<void>
8+
}
9+
10+
export function bindShortcuts(server: ViteDevServer): void {
11+
if (!server.httpServer || !process.stdin.isTTY || process.env.CI) {
12+
return
13+
}
14+
15+
server.config.logger.info(
16+
colors.dim(colors.green(' ➜')) +
17+
colors.dim(' press ') +
18+
colors.bold('h') +
19+
colors.dim(' to show help')
20+
)
21+
22+
let actionRunning = false
23+
24+
const onInput = async (input: string) => {
25+
// ctrl+c or ctrl+d
26+
if (input === '\x03' || input === '\x04') {
27+
await server.close().finally(() => process.exit(1))
28+
return
29+
}
30+
31+
if (actionRunning) return
32+
33+
if (input === 'h') {
34+
server.config.logger.info(
35+
[
36+
'',
37+
colors.bold(' Shortcuts'),
38+
...SHORTCUTS.map(
39+
(shortcut) =>
40+
colors.dim(' press ') +
41+
colors.bold(shortcut.key) +
42+
colors.dim(` to ${shortcut.description}`)
43+
)
44+
].join('\n')
45+
)
46+
}
47+
48+
const shortcut = SHORTCUTS.find((shortcut) => shortcut.key === input)
49+
if (!shortcut) return
50+
51+
actionRunning = true
52+
await shortcut.action(server)
53+
actionRunning = false
54+
}
55+
56+
process.stdin.setRawMode(true)
57+
58+
process.stdin.on('data', onInput).setEncoding('utf8').resume()
59+
60+
server.httpServer.on('close', () => {
61+
process.stdin.off('data', onInput).pause()
62+
})
63+
}
64+
65+
const SHORTCUTS: CLIShortcut[] = [
66+
{
67+
key: 'u',
68+
description: 'show server url',
69+
action(server) {
70+
server.config.logger.info('')
71+
server.printUrls()
72+
}
73+
},
74+
{
75+
key: 'o',
76+
description: 'open in browser',
77+
action(server) {
78+
server.openBrowser()
79+
}
80+
},
81+
{
82+
key: 'c',
83+
description: 'clear console',
84+
action(server) {
85+
server.config.logger.clearScreen('error')
86+
}
87+
},
88+
{
89+
key: 'q',
90+
description: 'quit',
91+
async action(server) {
92+
await server.close().finally(() => process.exit())
93+
}
94+
}
95+
]

0 commit comments

Comments
 (0)