Skip to content

fix: plugin shortcut support#21211

Merged
sapphi-red merged 4 commits intovitejs:mainfrom
edmundhung:fix-plugin-shortcut-support
Dec 8, 2025
Merged

fix: plugin shortcut support#21211
sapphi-red merged 4 commits intovitejs:mainfrom
edmundhung:fix-plugin-shortcut-support

Conversation

@edmundhung
Copy link
Contributor

@edmundhung edmundhung commented Dec 4, 2025

Fix #21166

I am terribly sorry having to come back to this the 3rd time. My previous attempt resolves the server restart issue only when no plugin defines their own shortcut using server.bindCliShortcuts().

When a plugin defines its own custom shortcut (e.g. x + enter), it works fine when the dev server is just started:

> pnpm run dev

> vite-plugin-shortcut-issue@0.0.0 dev /Users/edmund/Workspace/vite-plugin-shortcut-issue
> vite


  VITE v7.2.6  ready in 89 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
h

  Shortcuts
  press x + enter to log a message to the console
  press r + enter to restart the server
  press u + enter to show server url
  press o + enter to open in browser
  press c + enter to clear console
  press q + enter to quit
x
Hello World

However, if you change the shortcut message to Hello updated server defined in the config file and save it, the server restarts and this happens:

12:28:41 [vite] vite.config.ts changed, restarting server...
12:28:41 [vite] server restarted.
x
Hello updated server
Hello World

Here is a reproduction: https://github.com/edmundhung/vite-plugin-shortcut-issue

The issue here is when restartServer() creates a new server and the plugin calls server.bindCLIShortcuts(), a readline interface is also created. It gets detached because of my changes in #21166:

// Ensure the new server has no stale readline reference
newServer._rl = undefined

Another readline interface then get created with the stale shortcut options (the one that logs Hello World instead of the updated Hello updated server message) in

if (shortcutsOptions) {
shortcutsOptions.print = false
bindCLIShortcuts(
server,
shortcutsOptions,
// Skip environment checks since shortcuts were bound before restart
true,
)
}

Initially, I tried detaching the server._rl instance instead so we preserve the new readline instance created in the plugin:

-newServer._rl = undefined
+server._rl = undefined

But it runs into another issue: closing a readline interface on process.stdin causes already opened readline interfaces to stop receiving input.

This PR:

  1. Preserves the readline interface (_rl) across server restart (avoids issues when closing/reopening readline)
  2. Transfers _shortcutsOptions to the new server so plugin shortcuts can be properly merged when plugin register custom shortcut
  3. Maintains shortcut order (manually bound shortcuts stay above plugin shortcuts)

@edmundhung edmundhung force-pushed the fix-plugin-shortcut-support branch from 89b1b99 to ab27921 Compare December 4, 2025 13:53
@edmundhung edmundhung force-pushed the fix-plugin-shortcut-support branch from ab27921 to b0dce82 Compare December 4, 2025 14:12
@sapphi-red sapphi-red added p3-minor-bug An edge case that only affects very specific usage (priority) regression The issue only appears after a new release labels Dec 5, 2025
Copy link
Member

@sapphi-red sapphi-red left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've pushed a commit to simplify the state handling a bit.

@sapphi-red sapphi-red merged commit 6a3aca0 into vitejs:main Dec 8, 2025
32 of 33 checks passed
sapphi-red added a commit that referenced this pull request Dec 8, 2025
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
sapphi-red added a commit to vitejs/rolldown-vite that referenced this pull request Dec 12, 2025
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p3-minor-bug An edge case that only affects very specific usage (priority) regression The issue only appears after a new release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants