Skip to content

Conversation

@Info-Cado
Copy link

@Info-Cado Info-Cado commented Jan 19, 2026

Summary

  • Fix Ctrl+Backspace not triggering delete-word-backward on Windows Terminal and WSL

Problem

Windows Terminal and WSL terminals send different byte sequences for backspace:

  • Regular Backspace: \x7f (ASCII 127, DEL)
  • Ctrl+Backspace: \b (ASCII 8)

The current parser treats both as plain backspace without setting ctrl: true, so keybindings like ctrl+backspacedelete-word-backward never trigger.

Additional WSL Complexity

In WSL, process.platform returns 'linux', not 'win32', even though Windows Terminal sends Windows-style key sequences. This required detecting WSL via environment variables (WSL_DISTRO_NAME, WSL_INTEROP).

Solution

Added isWindowsTerminal() helper that detects:

  1. Native Windows (process.platform === 'win32')
  2. WSL (WSL_DISTRO_NAME or WSL_INTEROP environment variables)
Platform \b Handling Result
Windows/WSL Ctrl+Backspace { name: "backspace", ctrl: true }
macOS/Linux Ctrl+H (unchanged) { name: "h", ctrl: true }

Testing

  • All 41 tests pass
  • Tests use the same isWindowsTerminal() helper for platform-aware assertions
  • Manually verified in WSL with Windows Terminal

Fixes anomalyco/opencode#6991

Windows Terminal and many terminals send \b (ASCII 8) for Ctrl+Backspace,
but \x7f (ASCII 127) for regular Backspace. The parser was treating both
identically, causing Ctrl+Backspace to not trigger delete-word-backward.

Changes:
- \x7f now correctly parses as regular backspace (ctrl: false)
- \b now correctly parses as Ctrl+Backspace (ctrl: true)
- \x1b\x7f parses as Alt+Backspace (meta: true)
- \x1b\b parses as Alt+Ctrl+Backspace (meta: true, ctrl: true)

Fixes anomalyco/opencode#6991
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 19, 2026

@opentui/core

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/core@555

@opentui/react

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/react@555

@opentui/solid

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/solid@555

@opentui/core-darwin-arm64

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/core-darwin-arm64@555

@opentui/core-darwin-x64

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/core-darwin-x64@555

@opentui/core-linux-arm64

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/core-linux-arm64@555

@opentui/core-linux-x64

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/core-linux-x64@555

@opentui/core-win32-arm64

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/core-win32-arm64@555

@opentui/core-win32-x64

npm i https://pkg.pr.new/anomalyco/opentui/@opentui/core-win32-x64@555

commit: 91d10f2

@kommander
Copy link
Collaborator

I think that could make sense, it does not play well with existing expectations though it seems.

@Info-Cado
Copy link
Author

Info-Cado commented Jan 20, 2026

Thanks for the feedback @kommander!

You're right - I investigated the CI failures and I see the issue. The change breaks existing expectations around how \b (ASCII 8) is interpreted:

Current behavior: \b{ name: "h", ctrl: true } (via the generic ctrl+letter handler)

  • This then matches keybindings like { name: "h", ctrl: true, action: "backspace" } for single-char deletion

My change: \b{ name: "backspace", ctrl: true }

  • This matches { name: "backspace", ctrl: true, action: "delete-word-backward" } and triggers word deletion

The root cause is terminal semantics divergence:

  • Unix/macOS: \b = Ctrl+H (traditionally "h" with ctrl modifier)
  • Windows Terminal: \b = Ctrl+Backspace (a distinct key combination)

Options I see:

  1. Platform detection: Only interpret \b as Ctrl+Backspace on Windows (process.platform === 'win32'). This preserves existing behavior on macOS/Linux but enables the fix for Windows/WSL users.

  2. Keep existing behavior: Revert this change and document that Ctrl+Backspace requires Kitty keyboard protocol or modifyOtherKeys mode to work. The trade-off is that Windows Terminal users in WSL won't get word-deletion with Ctrl+Backspace.

  3. Add explicit keybinding: Keep \b as Ctrl+H, but add a default keybinding { name: "h", ctrl: true, action: "delete-word-backward" } to make Ctrl+H also delete words. This would be a behavior change but wouldn't affect key parsing.

What approach would you prefer? I'm happy to implement whichever makes most sense for the project.

BTW this comment was written by AI

@Info-Cado Info-Cado marked this pull request as draft January 20, 2026 05:39
On Windows, \b (ASCII 8) is Ctrl+Backspace.
On Unix/macOS, \b (ASCII 8) is Ctrl+H.

This preserves backwards compatibility on macOS/Linux while
enabling Ctrl+Backspace word deletion on Windows Terminal/WSL.
@Info-Cado
Copy link
Author

I've pushed a fix that uses platform detection (Option 1).

Changes:

  • On Windows (process.platform === 'win32'): \b{ name: "backspace", ctrl: true } (enables Ctrl+Backspace word deletion)
  • On macOS/Linux: \b{ name: "h", ctrl: true } (preserves existing Ctrl+H behavior)

This should:

  1. Pass all existing tests on macOS CI (behavior unchanged)
  2. Enable Ctrl+Backspace on Windows Terminal/WSL users

The tests now use platform detection to validate the expected behavior on each platform.

@Info-Cado Info-Cado marked this pull request as ready for review January 20, 2026 05:45
WSL reports process.platform as 'linux' but Windows Terminal still
sends Windows-style key sequences. Added isWindowsTerminal() helper
that checks for WSL_DISTRO_NAME and WSL_INTEROP environment variables.
@Info-Cado
Copy link
Author

I discovered an issue with the previous platform detection approach: WSL reports process.platform as 'linux', not 'win32', even though Windows Terminal sends Windows-style key sequences to WSL applications.

Updated the fix to also check for WSL environment variables:

  • WSL_DISTRO_NAME - set by WSL to the distribution name
  • WSL_INTEROP - set by WSL2 for Windows interop

This ensures Ctrl+Backspace works correctly for:

  1. Native Windows (process.platform === 'win32')
  2. WSL1/WSL2 (detected via environment variables)
  3. macOS/Linux (unchanged behavior - \b → Ctrl+H)

Tests updated to use the same detection logic.

import { parseKeypress, nonAlphanumericKeys, type ParsedKey, type KeyEventType } from "./parse.keypress"
import { Buffer } from "node:buffer"

const isWindowsTerminal = (): boolean => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The tests should probably use the same method as parse.keypress if it's not mocking anything?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Not able to ctrl + backspace or ctrl+del in /session command modal;

2 participants