fix(tui): restored compact editor border by default
- Restored the compact two-row `Editor` layout by default and gated the dedicated IME-safe bottom border behind `setImeSafeCursorLayout()`. - Added `tui.imeSafeCursor` as an opt-in appearance setting and applied it to initial and replacement editors. - Added regression coverage for compact default rendering while retaining terminal-local IME preedit protection. - Updated the TUI changelog for the opt-in compatibility layout.
This commit is contained in:
@@ -982,6 +982,17 @@ export const SETTINGS_SCHEMA = {
|
||||
},
|
||||
},
|
||||
|
||||
"tui.imeSafeCursor": {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
ui: {
|
||||
tab: "appearance",
|
||||
group: "Display",
|
||||
label: "IME-Safe Prompt Layout",
|
||||
description: "Move the prompt's bottom border to a separate row so macOS IME preedit cannot displace it",
|
||||
},
|
||||
},
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────
|
||||
// Model
|
||||
// ────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -680,6 +680,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
this.errorBannerContainer = new AnchoredLiveContainer();
|
||||
this.modelCycleContainer = new AnchoredLiveContainer();
|
||||
this.editor = new CustomEditor(getEditorTheme());
|
||||
this.editor.setImeSafeCursorLayout(settings.get("tui.imeSafeCursor"));
|
||||
this.editor.setUseTerminalCursor(this.ui.getShowHardwareCursor());
|
||||
this.editor.setAutocompleteMaxVisible(settings.get("autocompleteMaxVisible"));
|
||||
this.editor.onAutocompleteCancel = () => {
|
||||
@@ -3669,6 +3670,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
factory: ((tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager) => CustomEditor) | undefined,
|
||||
): void {
|
||||
const previousEditor = this.editor;
|
||||
nextEditor.setImeSafeCursorLayout(this.settings.get("tui.imeSafeCursor"));
|
||||
const previousText = previousEditor.getText();
|
||||
const nextEditor = factory
|
||||
? factory(this.ui, getEditorTheme(), this.keybindings)
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
|
||||
- Display LaTeX now renders `\underbrace`/`\overbrace` (and the bracket/paren variants) as drawn horizontal braces with centered labels, and stacks `\overset`/`\underset`/`\stackrel` annotations above/below the base instead of falling back to flat inline glyphs.
|
||||
- Display LaTeX renders multi-letter script words (`N_{turns}`) as raised/lowered blocks instead of ragged per-character Unicode sub/superscript glyphs; single letters and digits keep the compact Unicode forms.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed macOS IME marked text displacing the prompt editor border when entering fullwidth CJK punctuation ([#5563](https://github.com/can1357/oh-my-pi/issues/5563)).
|
||||
- Added opt-in `Editor.setImeSafeCursorLayout()` protection for macOS IME preedit while retaining the compact bordered layout by default ([#5563](https://github.com/can1357/oh-my-pi/issues/5563)).
|
||||
|
||||
## [16.5.2] - 2026-07-14
|
||||
|
||||
|
||||
@@ -382,6 +382,7 @@ export class Editor implements Component, Focusable {
|
||||
|
||||
#theme: EditorTheme;
|
||||
#useTerminalCursor = false;
|
||||
#imeSafeCursorLayout = false;
|
||||
|
||||
/** When set, replaces the normal cursor glyph at end-of-text with this ANSI-styled string. */
|
||||
cursorOverride: string | undefined;
|
||||
@@ -539,6 +540,11 @@ export class Editor implements Component, Focusable {
|
||||
this.#useTerminalCursor = useTerminalCursor;
|
||||
}
|
||||
|
||||
/** Render a dedicated bottom border so terminal-local IME preedit cannot shift editor chrome. */
|
||||
setImeSafeCursorLayout(enabled: boolean): void {
|
||||
this.#imeSafeCursorLayout = enabled;
|
||||
}
|
||||
|
||||
getUseTerminalCursor(): boolean {
|
||||
return this.#useTerminalCursor;
|
||||
}
|
||||
@@ -923,7 +929,13 @@ export class Editor implements Component, Focusable {
|
||||
if (marker) {
|
||||
const before = displayText.slice(0, layoutLine.cursorPos);
|
||||
const after = displayText.slice(layoutLine.cursorPos);
|
||||
if (after.length === 0 && inlineHint) {
|
||||
if (this.#imeSafeCursorLayout && after.length === 0 && borderVisible) {
|
||||
// Terminal frontends render IME marked text locally before committed bytes
|
||||
// reach the application. Keep the end-of-input cursor row empty to its
|
||||
// right so that insertion cannot shift box chrome onto the next row.
|
||||
displayText = before + marker;
|
||||
imeSafeCursorTail = true;
|
||||
} else if (after.length === 0 && inlineHint) {
|
||||
const availWidth = Math.max(0, lineContentWidth - displayWidth);
|
||||
const hintText = hintStyle(truncateToWidth(inlineHint, availWidth));
|
||||
displayText = before + marker + hintText;
|
||||
@@ -932,10 +944,6 @@ export class Editor implements Component, Focusable {
|
||||
displayText = this.#renderTerminalCursorMarker(before, marker, lineContentWidth);
|
||||
} else {
|
||||
displayText = before + marker + after;
|
||||
// Terminal frontends render IME marked text locally before committed bytes
|
||||
// reach the application. Keep the end-of-input cursor row empty to its
|
||||
// right so that insertion cannot shift box chrome onto the next row.
|
||||
imeSafeCursorTail = after.length === 0 && borderVisible;
|
||||
}
|
||||
}
|
||||
} else if (hasCursor && !this.#useTerminalCursor) {
|
||||
|
||||
@@ -853,11 +853,22 @@ describe("Editor component", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the terminal-cursor editor compact by default", () => {
|
||||
const editor = new Editor(defaultEditorTheme);
|
||||
editor.focused = true;
|
||||
editor.setUseTerminalCursor(true);
|
||||
editor.setText("ast");
|
||||
|
||||
const lines = editor.render(20).map(line => stripVTControlCharacters(line.replaceAll(CURSOR_MARKER, "")));
|
||||
expect(lines).toEqual(["+------------------+", "+- ast -+"]);
|
||||
});
|
||||
|
||||
it("keeps terminal-local IME preedit from displacing the editor border (#5563)", async () => {
|
||||
const width = 20;
|
||||
const terminal = new VirtualTerminal(width, 6, 1_000);
|
||||
const tui = new TUI(terminal, true);
|
||||
const editor = new Editor(defaultEditorTheme);
|
||||
editor.setImeSafeCursorLayout(true);
|
||||
tui.addChild(editor);
|
||||
tui.setFocus(editor);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user