fix(tui): proper Unicode width handling and combining mark support#26
Open
PTFOPlayer wants to merge 5 commits into
Open
fix(tui): proper Unicode width handling and combining mark support#26PTFOPlayer wants to merge 5 commits into
PTFOPlayer wants to merge 5 commits into
Conversation
- Fix .max(1) bug that made zero-width combining mark handling dead code in screen.rs (write_str, write_str_wrapped, write_str_wrapped_clipped, write_str_wrapped_skip_clipped), conversation.rs (line_height_for_text), and input_bar.rs (input_rows). Combining marks were treated as width-1 instead of being merged into the previous cell. - Remove unused unicode-segmentation dependency from Cargo.toml - Clean up dead code: unused has_newline variable and empty if block in input_bar.rs - Dynamic input bar height based on content, resizable sidebar width, Unicode-aware text wrapping and truncation across all TUI widgets
Add a field to to track continuation cells for wide characters that occupy 2 columns. When a wide character is written, the following column is marked as a continuation cell so the renderer skips it (the terminal already drew it as part of the wide character). Key changes: - Cell struct gains field, defaulting to false - New constructor for continuation cells - Screen's write_str/write_str_centered/write_str_right all place continuation cells after wide characters - Diff renderer skips continuation cells and tracks cursor position based on actual character display width - All widget code that manually sets cell chars now resets - Input bar handles empty content case to properly clear background - Add unit tests for wide character rendering and diff tracking
Three related bugs fixed: 1. ConfirmPrompt line_height overcounted: each diff line was counted using line_height_for_text (which accounts for wrapping), but the actual rendering truncates each diff line to 1 row. Changed to count each diff line as exactly 1 row, matching the rendering behavior. 2. Question rendering ignored wrapped row tracking: write_str_wrapped_clipped returns the last row written, but the code only did current_row += 1. If a question or answer wrapped to multiple lines, subsequent items would overlap. Now uses the return value to advance current_row correctly. 3. left_margin vs wrap_indent mismatch: User, Assistant, and System text rendering used left_margin=area.x (wrapping to left edge) but line_height_for_text used wrap_indent equal to the prefix width. This caused line_height to overestimate when text wrapped. Fixed all rendering calls to use left_margin = area.x + prefix_width, matching the wrap_indent used in height calculation. Also added 3 new tests: - test_confirm_prompt_line_height_matches_rendering - test_confirm_prompt_does_not_create_stairs - test_question_wrapping_height_matches
- Fix dim interface and ghost text bugs: add \x1b[0m reset before each cell's style in render_diff() to prevent ANSI attributes (dim, bold, background colors) from leaking into subsequent cells - Move streaming/thinking spinner from conversation area to input bar: - Add streaming state to InputBarWidget with animated spinner frames - Show '⠋ Thinking…' / '⠋ Responding…' in input bar during streaming - Block all keyboard input during streaming except Ctrl+C and Ctrl+D - Remove SpinnerWidget from TuiApp (no longer needed separately) - Clean up unused SpinnerWidget import and field from app.rs
…lp dismiss - Extract WrapConfig struct to consolidate the three duplicated wrapping implementations (write_str_wrapped, write_str_wrapped_clipped, write_str_wrapped_skip_clipped) into a single write_wrapped method. The original methods are now thin convenience wrappers. - Add dismiss_help() helper to replace repeated help_visible/help_scroll reset pairs in the help overlay event handler. - Improve ANSI render_diff to deduplicate style attributes and emit fewer escape sequences by tracking active fg/bg/style state. - Clean up else-if chains in help key handling for clarity. - Add comprehensive unit tests for wrapping, clipping, scrolling, style deduplication, and space preservation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.