From 7d937c158959e76443a02f740b10e251d14dbd8c Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Wed, 31 Jan 2024 21:57:34 +0800 Subject: [PATCH] Add CLI shortcuts (#9159) * Add CLI shortcuts * Update changeset * Remove server urls shortcut * feat: improve CLI shortcut formatting * chore: remove unused import * Cleanup * Cleanup --------- Co-authored-by: Nate Moore Co-authored-by: Emanuele Stoppa --- .changeset/old-cherries-beg.md | 9 +++++++++ packages/astro/src/core/dev/restart.ts | 18 ++++++++++++++---- packages/astro/src/core/logger/vite.ts | 14 ++++++++++++-- packages/astro/src/core/messages.ts | 5 +++++ 4 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 .changeset/old-cherries-beg.md diff --git a/.changeset/old-cherries-beg.md b/.changeset/old-cherries-beg.md new file mode 100644 index 0000000000..cf074297e7 --- /dev/null +++ b/.changeset/old-cherries-beg.md @@ -0,0 +1,9 @@ +--- +'astro': minor +--- + +Adds CLI shortcuts as an easter egg for the dev server: + +- `o + enter`: opens the site in your browser +- `q + enter`: quits the dev server +- `h + enter`: prints all available shortcuts diff --git a/packages/astro/src/core/dev/restart.ts b/packages/astro/src/core/dev/restart.ts index 3d77ef0c0c..23e6af369a 100644 --- a/packages/astro/src/core/dev/restart.ts +++ b/packages/astro/src/core/dev/restart.ts @@ -137,7 +137,7 @@ export async function createContainerWithAutomaticRestart({ } else { // Restart success. Add new watches because this is a new container with a new Vite server restart.container = result; - addWatches(); + setupContainer(); resolveRestart(null); } restartComplete = new Promise((resolve) => { @@ -153,8 +153,8 @@ export async function createContainerWithAutomaticRestart({ }; } - // Set up watches - function addWatches() { + // Set up watchers, vite restart API, and shortcuts + function setupContainer() { const watcher = restart.container.viteServer.watcher; watcher.on('change', handleChangeRestart('Configuration file updated.')); watcher.on('unlink', handleChangeRestart('Configuration file removed.')); @@ -163,7 +163,17 @@ export async function createContainerWithAutomaticRestart({ // Restart the Astro dev server instead of Vite's when the API is called by plugins. // Ignore the `forceOptimize` parameter for now. restart.container.viteServer.restart = () => handleServerRestart(); + + // Set up shortcuts, overriding Vite's default shortcuts so it works for Astro + restart.container.viteServer.bindCLIShortcuts({ + customShortcuts: [ + // Disable Vite's builtin "r" (restart server), "u" (print server urls) and "c" (clear console) shortcuts + { key: 'r', description: '' }, + { key: 'u', description: '' }, + { key: 'c', description: '' }, + ], + }); } - addWatches(); + setupContainer(); return restart; } diff --git a/packages/astro/src/core/logger/vite.ts b/packages/astro/src/core/logger/vite.ts index 8a3079158b..9604a68f05 100644 --- a/packages/astro/src/core/logger/vite.ts +++ b/packages/astro/src/core/logger/vite.ts @@ -3,6 +3,7 @@ import stripAnsi from 'strip-ansi'; import type { Logger as ViteLogger, Rollup, LogLevel } from 'vite'; import { isAstroError } from '../errors/errors.js'; import { isLogLevelEnabled, type Logger as AstroLogger } from './core.js'; +import { serverShortcuts as formatServerShortcuts } from '../messages.js'; const PKG_PREFIX = fileURLToPath(new URL('../../../', import.meta.url)); const E2E_PREFIX = fileURLToPath(new URL('../../../e2e', import.meta.url)); @@ -16,6 +17,10 @@ const vitePageReloadMsg = /page reload (.*)( \(.*\))?/; const viteHmrUpdateMsg = /hmr update (.*)/; // capture "vite v5.0.0 building SSR bundle for production..." and "vite v5.0.0 building for production..." messages const viteBuildMsg = /vite.*building.*for production/; +// capture "\n Shortcuts" messages +const viteShortcutTitleMsg = /^\s*Shortcuts\s*$/s; +// capture "press * + enter to ..." messages +const viteShortcutHelpMsg = /press\s+(.*?)\s+to\s+(.*)$/s; export function createViteLogger( astroLogger: AstroLogger, @@ -42,10 +47,15 @@ export function createViteLogger( if (isAstroSrcFile(m[1])) return; astroLogger.info('watch', m[1]); } - // Don't log Vite build messages - else if (viteBuildMsg.test(stripped)) { + // Don't log Vite build messages and shortcut titles + else if (viteBuildMsg.test(stripped) || viteShortcutTitleMsg.test(stripped)) { // noop } + // Log shortcuts help messages without indent + else if (viteShortcutHelpMsg.test(stripped)) { + const [, key, label] = viteShortcutHelpMsg.exec(stripped)! as string[]; + astroLogger.info('SKIP_FORMAT', formatServerShortcuts({ key, label })); + } // Fallback else { astroLogger.info('vite', msg); diff --git a/packages/astro/src/core/messages.ts b/packages/astro/src/core/messages.ts index b105e985cb..5b424944fe 100644 --- a/packages/astro/src/core/messages.ts +++ b/packages/astro/src/core/messages.ts @@ -95,6 +95,11 @@ export function serverStart({ return messages.filter((msg) => typeof msg === 'string').join('\n'); } +/** Display custom dev server shortcuts */ +export function serverShortcuts({ key, label }: { key: string; label: string }): string { + return [dim(' Press'), key, dim('to'), label].join(' '); +} + export function telemetryNotice() { const headline = blue(`▶ Astro collects anonymous usage data.`); const why = ' This information helps us improve Astro.';