Skip to content

Improve table rendering: inline markdown, wrap, alignment, autolink#77

Open
jinzex wants to merge 8 commits intohanebox:releasefrom
jinzex:jinzex/table-improvement
Open

Improve table rendering: inline markdown, wrap, alignment, autolink#77
jinzex wants to merge 8 commits intohanebox:releasefrom
jinzex:jinzex/table-improvement

Conversation

@jinzex
Copy link
Copy Markdown

@jinzex jinzex commented Apr 24, 2026

Summary

Improve markdown table rendering in the terminal view so table cells render inline markdown, respect column alignment, wrap cleanly when the table is wider than the terminal, autolink bare URLs, and let keyboard navigation reach every link in a row. Also fixes a false-positive unsaved-changes dialog.

What's in

  • Inline markdown in table cells. [link](url), **bold**, *italic*, `code`, ~~strike~~, [[wiki]] now render like they do in any other paragraph (previously cells showed raw source).
  • Column alignment. :--- / ---: / :---: in the separator row drive Left/Right/Center padding.
  • Wide tables wrap cleanly. Columns cap against the terminal width (shrink-widest-first with a floor); cells wrap at whitespace; row height grows to the tallest cell.
  • Bare URL autolink. https://example.com pasted directly renders as a styled link and opens with Enter, inside and outside tables.
  • Navigable links. Arrow-key cycling reaches every [text](url) and bare URL in a row (previously only the first one per row was navigable). "Open ↗" hint on the cursored row.
  • Fix: edit-mode → Esc with no edits no longer opens the unsaved-changes dialog when the file ends with a trailing newline.

Example to reproduce

Save as any .md file and open it with ekphos:

## 1. Inline markdown inside cells

| Feature         | Status   | Notes                                                      |
| --------------- | -------- | ---------------------------------------------------------- |
| **warp decode** | `proto`  | see [docs](https://example.com), [more](https://example.com/b) |
| *MxFp8×BF16*    | `ok`     | two kernels: `gate+up`, then `down`                        |
| TRT-LLM Gen     | `stable` | tensor cores, **128 experts**                              |

## 2. Column alignment

| Name    | Value | Score |
| :------ | :---: | ----: |
| alpha   |   1   |   100 |
| beta    |  20   |  2000 |
| gamma   | 300   | 30000 |

## 3. Wide cells wrap

| Step | Action                                                                                                                      |
| ---- | --------------------------------------------------------------------------------------------------------------------------- |
| 1    | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. |
| 2    | Pack my box with five dozen liquor jugs, then label each one carefully with the date and destination.                       |

## 4. Bare URL autolinking

| Site  | URL                                |
| ----- | ---------------------------------- |
| Plain | https://example.com                |
| Path  | https://example.com/docs?section=1 |

## 5. Newline support <br>

| Name  | Step                               |
| ----- | ---------------------------------- |
| A     | step 1 <br>step 2                  |
| B     | step b.1 <br>step b.2 <br> step b.3|

Before / after

Before After

Test plan

  • cargo test --release — 396 pass, 0 fail.
  • cargo build --release and open the example above — all four tables render correctly.
  • Arrow keys cycle through every link in a row; Enter opens.
  • Resize terminal — wide tables reflow.
  • Press e and then Esc on an unchanged note — no unsaved-changes dialog.

jinzex and others added 8 commits April 24, 2026 01:01
Render inline markdown (links, bold, italic, code, wiki links) inside
table cells and wire up Enter-to-open for the first [text](url) per
cell, including the "Open ↗" hint on the cursor'd row. Previously
table cells rendered their raw source, so `[label](url)` appeared
literally and columns reserved space for hidden markup. Scoped to
simple scenarios: one markdown link per cell, no bare-URL autolinking.

Also fix has_unsaved_changes to compare line-by-line with the same
str::lines() semantics that enter_edit_mode uses. The old raw-string
compare fired a false positive whenever a note ended in "\n" (most
files), making edit-then-Esc round-trips prompt the unsaved-changes
dialog even when no edits were made.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parse :--- / ---: / :---: in the separator row to derive per-column
alignment. Fix calc_formatting_shrinkage counting `[x](url)` as
url_len+3 instead of url_len+4, which drifted borders by N on rows
with N links.

Adds unit tests for cell_visible_width, extract_simple_table_links,
and Alignment::from_separator_cell.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Render bare URLs as styled links everywhere and emit them to
item_links_at so Enter opens them. Strips trailing sentence punctuation
per GFM; skips URLs that fall inside an existing [label](url) so they
don't double-emit. Table cells fall back to a bare-URL scan when no
bracket link is present.

Unit tests for detect_bare_url_len (scheme, delimiters, punctuation,
no-match) and for extract_simple_table_links bare-URL + precedence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Alignment is already visible in how data rows are padded, so showing
`:---` / `---:` / `:---:` in the rendered separator duplicates source
syntax that most markdown renderers strip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wide tables no longer push later columns off-screen. Column widths cap
against the terminal area (shrink-widest-first with a floor), and cells
wrap to multiple visual lines at whitespace boundaries. Row height grows
to match the tallest cell.

Wrapping preserves inline markdown: parse_inline_formatting runs once
per cell, then spans are distributed across visual lines — atomic spans
(links, bold, italic, code, wiki) stay intact, plain-text spans break
at whitespace. Avoids corrupting constructs that span wrap boundaries.

Drop the one-link-per-cell limit in extract_simple_table_links so every
[text](url) and bare URL in a row is navigable via arrow-key cycling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cell_visible_width measured by chars().count(), so a cell like
"🟡In-Progress" was sized at 12 cols when it actually renders in 13.
Column widths under-reserved, causing emoji/CJK cells to overflow and
wrap unnecessarily even when the terminal had room.

Switch to UnicodeWidthStr::width and subtract the markdown-marker
char count (markers are all ASCII = 1 col each).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Table cells can now contain GFM-style <br>, <br/>, <br />
(case-insensitive) to split content across multiple visual lines.
Each logical line parses and wraps independently; they stack
vertically within the cell, and row height grows to fit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
calc_wrapped_height measured each word with raw width — including
markdown markers — so a token like [#cdd-rl-post-training](https://...)
counted ~80 raw cols when it actually renders as ~21. Lines with long
markdown links over-reserved height, leaving blank padding rows below
the visible content.

Switch to cell_visible_width per word so the strip-shrinkage already
used for tables applies here too. Handles the common single-word link
case (multi-word constructs with internal spaces are a separate, rarer
case in non-table content).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant