Skip to content

fix: pass the typed character through with each key [patch] - #189

Merged
matt-edmondson merged 4 commits into
mainfrom
fix/152-keychar
Sep 30, 2026
Merged

matt-edmondson merged 4 commits into
mainfrom
fix/152-keychar

Conversation

@matt-edmondson

@matt-edmondson matt-edmondson commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #152

Before: SpectreConsoleProvider.ReadInputAsync returned InputResult.FromKey(keyInfo.Key, keyInfo.Modifiers) and dropped keyInfo.KeyChar. An element saw ! as D1 + Shift and couldn't tell it from 1. /, ? and @ arrived as layout-dependent Oem* keys, and Caps Lock was lost.

After: when KeyChar is printable (not '\0' and not a control character), InputResult.Character is filled in. Type, Key and Modifiers are unchanged, so key-based handlers such as InteractiveDemo behave exactly as before. Escape and Ctrl+C still produce Exit.

How:

  • The ConsoleKeyInfo → InputResult conversion moves into internal static SpectreConsoleProvider.ToInputResult, so it can be tested without a real console.
  • ReadInputAsync reads through a key-reader delegate. The public constructor still uses Console.ReadKey(true). A new internal constructor accepts another reader, so tests can drive ReadInputAsync itself.

Tests in SpectreConsoleProviderTests:

  • ToInputResultKeepsThePrintableCharacter covers Shift+D1 → '!', 1, A/a, Shift+Oem2 → '?' and a non-ASCII é. All 6 cases fail on main and pass with the fix.
  • ReadInputAsyncReturnsTheTypedCharacter drives a Shift+1 key through ReadInputAsync and checks that it arrives as '!'.
  • These tests guard the existing behaviour:
    • ToInputResultLeavesTheCharacterUnsetForNonPrintableKeys (arrow, Enter, Tab, Backspace)
    • ToInputResultTreatsEscapeAsExit and ToInputResultTreatsControlCAsExit
    • ToInputResultTreatsPlainCAsACharacter
  • Full TUI.Test suite: 240/240. SonarCloud reports 100% coverage on new code.

Main (with #187 and #188) is merged in.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XMvgrK1uK13jn4qeVXxDi1

SpectreConsoleProvider returned only the key and modifiers from
Console.ReadKey, dropping KeyChar, so no element could tell '!' from '1',
see Caps Lock, or follow a non-US layout. A printable KeyChar now fills
InputResult.Character alongside the key and modifiers, so key-based
handlers keep working. The conversion moves into an internal
ToInputResult so it can be tested without a console.

Fixes #152

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XMvgrK1uK13jn4qeVXxDi1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XMvgrK1uK13jn4qeVXxDi1
# Conflicts:
#	TUI.Test/SpectreConsoleProviderTests.cs
ReadInputAsync called Console.ReadKey directly, so no test could reach it.
An internal constructor now takes the key reader, and a test checks that
a Shift+1 read arrives as '!' end to end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XMvgrK1uK13jn4qeVXxDi1
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 3bfc17b into main Sep 30, 2026
14 checks passed
@matt-edmondson
matt-edmondson deleted the fix/152-keychar branch September 30, 2026 08:33
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.

Typed characters never reach elements: SpectreConsoleProvider drops ConsoleKeyInfo.KeyChar, so text input and shifted symbols are impossible

2 participants