fix(tui): default Ctrl+Z to undo on Windows (#21138)
This commit is contained in:
@@ -761,6 +761,7 @@ function App(props: { onSnapshot?: () => Promise<string[]> }) {
|
|||||||
keybind: "terminal_suspend",
|
keybind: "terminal_suspend",
|
||||||
category: "System",
|
category: "System",
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
enabled: tuiConfig.keybinds?.terminal_suspend !== "none",
|
||||||
onSelect: () => {
|
onSelect: () => {
|
||||||
process.once("SIGCONT", () => {
|
process.once("SIGCONT", () => {
|
||||||
renderer.resume()
|
renderer.resume()
|
||||||
|
|||||||
@@ -148,5 +148,7 @@ const TIPS = [
|
|||||||
"Use {highlight}/review{/highlight} to review uncommitted changes, branches, or PRs",
|
"Use {highlight}/review{/highlight} to review uncommitted changes, branches, or PRs",
|
||||||
"Run {highlight}/help{/highlight} or {highlight}Ctrl+X H{/highlight} to show the help dialog",
|
"Run {highlight}/help{/highlight} or {highlight}Ctrl+X H{/highlight} to show the help dialog",
|
||||||
"Use {highlight}/rename{/highlight} to rename the current session",
|
"Use {highlight}/rename{/highlight} to rename the current session",
|
||||||
"Press {highlight}Ctrl+Z{/highlight} to suspend the terminal and return to your shell",
|
...(process.platform === "win32"
|
||||||
|
? ["Press {highlight}Ctrl+Z{/highlight} to undo changes in your prompt"]
|
||||||
|
: ["Press {highlight}Ctrl+Z{/highlight} to suspend the terminal and return to your shell"]),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -111,7 +111,15 @@ export namespace TuiConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.result.keybinds = Config.Keybinds.parse(acc.result.keybinds ?? {})
|
const keybinds = { ...(acc.result.keybinds ?? {}) }
|
||||||
|
if (process.platform === "win32") {
|
||||||
|
// Native Windows terminals do not support POSIX suspend, so prefer prompt undo.
|
||||||
|
keybinds.terminal_suspend = "none"
|
||||||
|
keybinds.input_undo ??= unique(["ctrl+z", ...Config.Keybinds.shape.input_undo.parse(undefined).split(",")]).join(
|
||||||
|
",",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
acc.result.keybinds = Config.Keybinds.parse(keybinds)
|
||||||
|
|
||||||
const deps: Promise<void>[] = []
|
const deps: Promise<void>[] = []
|
||||||
if (acc.result.plugin?.length) {
|
if (acc.result.plugin?.length) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Global } from "../../src/global"
|
|||||||
import { Filesystem } from "../../src/util/filesystem"
|
import { Filesystem } from "../../src/util/filesystem"
|
||||||
|
|
||||||
const managedConfigDir = process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR!
|
const managedConfigDir = process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR!
|
||||||
|
const wintest = process.platform === "win32" ? test : test.skip
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await Config.invalidate(true)
|
await Config.invalidate(true)
|
||||||
@@ -441,6 +442,53 @@ test("merges keybind overrides across precedence layers", async () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
wintest("defaults Ctrl+Z to input undo on Windows", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const config = await TuiConfig.get()
|
||||||
|
expect(config.keybinds?.terminal_suspend).toBe("none")
|
||||||
|
expect(config.keybinds?.input_undo).toBe("ctrl+z,ctrl+-,super+z")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
wintest("keeps explicit input undo overrides on Windows", async () => {
|
||||||
|
await using tmp = await tmpdir({
|
||||||
|
init: async (dir) => {
|
||||||
|
await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ keybinds: { input_undo: "ctrl+y" } }))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const config = await TuiConfig.get()
|
||||||
|
expect(config.keybinds?.terminal_suspend).toBe("none")
|
||||||
|
expect(config.keybinds?.input_undo).toBe("ctrl+y")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
wintest("ignores terminal suspend bindings on Windows", async () => {
|
||||||
|
await using tmp = await tmpdir({
|
||||||
|
init: async (dir) => {
|
||||||
|
await Bun.write(path.join(dir, "tui.json"), JSON.stringify({ keybinds: { terminal_suspend: "alt+z" } }))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const config = await TuiConfig.get()
|
||||||
|
expect(config.keybinds?.terminal_suspend).toBe("none")
|
||||||
|
expect(config.keybinds?.input_undo).toBe("ctrl+z,ctrl+-,super+z")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test("OPENCODE_TUI_CONFIG provides settings when no project config exists", async () => {
|
test("OPENCODE_TUI_CONFIG provides settings when no project config exists", async () => {
|
||||||
await using tmp = await tmpdir({
|
await using tmp = await tmpdir({
|
||||||
init: async (dir) => {
|
init: async (dir) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user