From 1626799f3dc90ec2c65f67b04adbd2917132d510 Mon Sep 17 00:00:00 2001 From: roboomp Date: Tue, 14 Jul 2026 18:50:43 +0000 Subject: [PATCH] fix(tui): classified underscore as word char for ctrl+w `getWordNavKind` ran the `\p{P}` punctuation test before the `_` check, so underscore (Unicode `Pc`) returned "delimiter" and `moveWordLeft` stopped at each underscore. Ctrl+W deleted only the trailing segment of snake_case identifiers. Reordered the underscore check ahead of the punctuation/symbol test and removed the dead `ch === "_"` branch. Fixes #4776 --- packages/tui/CHANGELOG.md | 4 ++++ packages/tui/src/utils.ts | 3 ++- packages/tui/test/editor.test.ts | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index b6d4864c9..714b6f07b 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed `Ctrl+W` (delete word backward) stopping at underscores in snake_case identifiers; `_` is now classified as a word character so `allowed_openai_params` deletes as a single word ([#4776](https://github.com/can1357/oh-my-pi/issues/4776)). + ## [16.3.10] - 2026-07-06 ### Fixed diff --git a/packages/tui/src/utils.ts b/packages/tui/src/utils.ts index 8c12b6a52..c54c5b825 100644 --- a/packages/tui/src/utils.ts +++ b/packages/tui/src/utils.ts @@ -394,6 +394,7 @@ export function getWordNavKind(grapheme: string): WordNavKind { const ch = firstCodePointChar(grapheme); if (!ch) return "other"; if (WORD_NAV_RE_WHITESPACE.test(ch)) return "whitespace"; + if (ch === "_") return "word"; if (WORD_NAV_RE_PUNCT.test(ch) || WORD_NAV_RE_SYMBOL.test(ch)) return "delimiter"; if ( WORD_NAV_RE_HAN.test(ch) || @@ -403,7 +404,7 @@ export function getWordNavKind(grapheme: string): WordNavKind { ) { return "cjk"; } - if (ch === "_" || WORD_NAV_RE_LETTER.test(ch) || WORD_NAV_RE_NUMBER.test(ch)) return "word"; + if (WORD_NAV_RE_LETTER.test(ch) || WORD_NAV_RE_NUMBER.test(ch)) return "word"; return "other"; } diff --git a/packages/tui/test/editor.test.ts b/packages/tui/test/editor.test.ts index d451c758e..e6e730900 100644 --- a/packages/tui/test/editor.test.ts +++ b/packages/tui/test/editor.test.ts @@ -590,6 +590,11 @@ describe("Editor component", () => { editor.handleInput("\x17"); expect(editor.getText()).toBe("foo bar"); + // snake_case identifier deletes as a single word (issue #4776) + editor.setText("allowed_openai_params"); + editor.handleInput("\x17"); + expect(editor.getText()).toBe(""); + // Delete across multiple lines editor.setText("line one\nline two"); editor.handleInput("\x17");