Skip to content

fix(ui): correct styled table width calculations#20042

Merged
devr0306 merged 17 commits intomainfrom
fix-styled-table-widths
Feb 27, 2026
Merged

fix(ui): correct styled table width calculations#20042
devr0306 merged 17 commits intomainfrom
fix-styled-table-widths

Conversation

@devr0306
Copy link
Contributor

@devr0306 devr0306 commented Feb 23, 2026

Summary

This pull request addresses a long-standing issue where tables displayed in the CLI would often have misaligned columns or unexpected text wrapping when their content included markdown. By introducing a sophisticated markdown parser that correctly interprets and measures the rendered width of styled text, the TableRenderer now ensures that tables maintain their structural integrity and readability, regardless of the complexity of their content. This enhancement significantly improves the visual presentation of information within the command-line interface.

Details

  • Accurate Markdown Width Calculation: Implemented a new markdown parsing mechanism that accurately calculates the rendered width of text within table cells, rather than using the raw markdown string length. This prevents incorrect column widths and text wrapping issues caused by markdown syntax.
  • Enhanced Markdown Rendering: The TableRenderer now correctly renders various inline markdown styles, including bold, italic, combined bold/italic, strikethrough, links, and underlines, directly within table headers and rows.
  • Improved Code Snippet Handling: Markdown syntax within inline code snippets (e.g., not bold) is now correctly preserved and not parsed, ensuring that code examples are displayed as intended.
  • Refactored Cell Rendering: The internal rendering of table cells has been updated to use Box components for better layout control and consistent padding, and the RenderInline component has been removed as its functionality is now integrated into the core parsing logic.
  • Parser Utility: Created a common parsing utility used by both TableRenderer and InlineMarkdownRenderer to make markdown parsing and rendering consistent and maintainable.
  • Comprehensive Test Coverage: Added extensive new test cases to validate the correct rendering and width calculation for complex markdown scenarios, including nested styles, URLs, and code snippets, ensuring the robustness of the changes.

Related Issues

Fixes #18942

How to Validate

Ask Gemini "Show me a markdown table with styled characters". The following should work:

  1. Column widths should be properly calculated and borders should be properly rendered
  2. Text styles should be correctly applied
  3. Styles inside of code snippets should not be applied

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@devr0306 devr0306 requested a review from a team as a code owner February 23, 2026 17:34
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @devr0306, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a long-standing issue where tables displayed in the CLI would often have misaligned columns or unexpected text wrapping when their content included markdown. By introducing a sophisticated markdown parser that correctly interprets and measures the rendered width of styled text, the TableRenderer now ensures that tables maintain their structural integrity and readability, regardless of the complexity of their content. This enhancement significantly improves the visual presentation of information within the command-line interface.

Highlights

  • Accurate Markdown Width Calculation: Implemented a new markdown parsing mechanism that accurately calculates the rendered width of text within table cells, rather than using the raw markdown string length. This prevents incorrect column widths and text wrapping issues caused by markdown syntax.
  • Enhanced Markdown Rendering: The TableRenderer now correctly renders various inline markdown styles, including bold, italic, combined bold/italic, strikethrough, links, and underlines, directly within table headers and rows.
  • Improved Code Snippet Handling: Markdown syntax within inline code snippets (e.g., **not bold**) is now correctly preserved and not parsed, ensuring that code examples are displayed as intended.
  • Refactored Cell Rendering: The internal rendering of table cells has been updated to use Box components for better layout control and consistent padding, and the RenderInline component has been removed as its functionality is now integrated into the core parsing logic.
  • Comprehensive Test Coverage: Added extensive new test cases to validate the correct rendering and width calculation for complex markdown scenarios, including nested styles, URLs, and code snippets, ensuring the robustness of the changes.
Changelog
  • packages/cli/src/ui/utils/TableRenderer.test.tsx
    • Added new test cases to verify correct markdown rendering and width calculation for various inline styles.
    • Included tests for nested markdown, URL rendering, and preservation of markdown within code snippets.
    • Verified that column widths are calculated based on rendered text, not raw markdown.
  • packages/cli/src/ui/utils/TableRenderer.tsx
    • Introduced ansiColorize for consistent ANSI escape code application based on Ink's colorization.
    • Implemented parseMarkdownToANSI to convert markdown text into ANSI-escaped strings, handling various inline markdown types.
    • Created parseMarkdownToStyledChars to generate StyledChar arrays from markdown, ensuring accurate rendered width calculations.
    • Updated styledHeaders and styledRows to use parseMarkdownToStyledChars for markdown-aware content processing.
    • Adjusted the column width scaling logic to prevent division by zero.
    • Refactored renderCell to directly render content and removed the RenderInline component.
    • Changed row rendering to use Box components with paddingX for improved layout and consistent cell spacing.
    • Modified the key generation logic in renderTableBody for header rows.
  • packages/cli/src/ui/utils/snapshots/TableRenderer.test.tsx.snap
    • Updated snapshots to reflect the expected output for new markdown rendering and width calculation test cases.
Activity
  • The author devr0306 initiated this pull request to fix issues related to styled table widths.
  • New utility functions for markdown parsing and ANSI colorization were introduced to address the core problem.
  • Extensive new unit tests were added to TableRenderer.test.tsx to validate the new markdown rendering and width calculation logic across various scenarios.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-cli gemini-cli bot added the priority/p1 Important and should be addressed in the near term. label Feb 23, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses an issue with table column width calculation when cells contain markdown by introducing a new markdown-to-ANSI parser for accurate width measurement. While the changes are supported by new tests, the new markdown parsing logic in TableRenderer.tsx duplicates and diverges from the existing InlineMarkdownRenderer.tsx. This creates separate implementations, potentially leading to UI inconsistencies and increased maintenance burden. It is recommended to unify this logic into a single, shared utility.

@devr0306 devr0306 changed the title Fix styled table widths fix(ui): fix styled table widths Feb 23, 2026
@gemini-cli gemini-cli bot added area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Feb 23, 2026
@github-actions
Copy link

github-actions bot commented Feb 23, 2026

Size Change: +1.54 kB (+0.01%)

Total Size: 25.7 MB

Filename Size Change
./bundle/gemini.js 25.2 MB +1.54 kB (+0.01%)
ℹ️ View Unchanged
Filename Size
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 221 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 227 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 11.5 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB
./bundle/sandbox-macos-strict-open.sb 4.82 kB
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB

compressed-size-action

@devr0306 devr0306 changed the title fix(ui): fix styled table widths fix(ui): correct styled table width calculations Feb 23, 2026
Copy link
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

Test Warnings (Color Resolution): Because the darkTheme configuration intentionally uses an empty string "" for the default Foreground to fall back
to the terminal's default color, passing "" into resolveColor was causing an explosion of [ColorUtils] Could not resolve color "" warnings during
test execution. I added an early return to resolveColor in packages/cli/src/ui/themes/color-utils.ts to cleanly handle empty or whitespace-only
color strings and eliminate the noise.

@@ -0,0 +1,184 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

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

engineering practices tips: when performing a refactor like this you need to do it in a way that minimizes the diff. Right not it is not clear how much of the logic is identical and how much changed. To make this clear you could either keep the parsuingUtils.ts code in InlineMarkdownRenderer.tsx and change the behavior there or first send a PR to move it to parsuingUtils and then a follow up pr in the chain that refactors it to have the new behavior. This way as a human I can review 10X more effectively than in the current form.

Copy link
Contributor

Choose a reason for hiding this comment

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

Gemini may be confused but it believes the refactor did make some changes so would be helpful to write in a form that I can productively review.

  1. Recursive Parsing (Nested Styles)
  • Old: Only parsed a single level of markdown. If you provided bold with italic, it would strip the ** markers but render bold with italic
    directly as plain text.
  • New: The parsing is now recursive. When matching markers like ..., ..., ..., or ..., it calls parseMarkdownToANSI on the inner
    slice of text. This means nested styles like bold with italic will now correctly render both bold and italic traits.
  1. Formatted Link Text
  • Old: Link labels were treated strictly as plain text. For example, Google would render the raw asterisks.
  • New: Because of the recursive capability mentioned above, link text is also recursively parsed. Google will now render "Google" as bold
    text alongside the URL.
  1. Support for *** (Bold + Italic)
  • Old: The regex only matched ** or */_. A string like Text would fall back to the bold regex (**), rendering Text in bold (leaving the inner
    asterisks visible).
  • New: The regex was updated to explicitly capture ***.*?***, and a dedicated block was added to apply both chalk.bold() and chalk.italic()
    formatting for these tags.
  1. Output Format
  • Old: Emitted an array of React DOM nodes ({...}).
  • New: Emits a single pure string containing raw ANSI escape codes using chalk. This string is then passed to a single node back in
    InlineMarkdownRenderer.tsx, which allows Ink to apply the ANSI codes itself.
  1. Error Handling Removed
  • Old: The internal loop wrapped tag evaluations in a try...catch block that emitted a debugLogger.warn('Error parsing inline markdown part...', e) if
    parsing failed, gracefully failing back to raw text.
  • New: The try...catch block has been omitted entirely. The code assumes string slice evaluations and recursive calls are strictly safe under the
    regex matches.

Copy link
Contributor Author

@devr0306 devr0306 Feb 24, 2026

Choose a reason for hiding this comment

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

I added some changes to make it similar to InlineMarkdownRenderer and here are the major changes now:

  • 1, 3, 4 from the things Gemini pointed out
  • Got rid of keys for the <Text/> nodes. Before this, a list of nodes was rendered which required keys but now the string itself is preprocessed and a single node is rendered, leading to no key required.
  • Added color parsing as well. For now, it only works to parse the text into certain theme colors like primary, accent, and link.

@devr0306 devr0306 requested a review from a team as a code owner February 26, 2026 19:46
Copy link
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

lgtm

@devr0306 devr0306 added this pull request to the merge queue Feb 27, 2026
Merged via the queue into main with commit ecfa4e0 Feb 27, 2026
27 checks passed
@devr0306 devr0306 deleted the fix-styled-table-widths branch February 27, 2026 01:43
BryanBradfo pushed a commit to BryanBradfo/gemini-cli that referenced this pull request Mar 5, 2026
liamhelmer pushed a commit to badal-io/gemini-cli that referenced this pull request Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proper widths for styled text in tables

2 participants