Skip to content

Show code in color in the preview and the details - #115

Open
thisisgm wants to merge 2 commits into
omacom:mainfrom
thisisgm:code-colours
Open

thisisgm wants to merge 2 commits into
omacom:mainfrom
thisisgm:code-colours

Conversation

@thisisgm

@thisisgm thisisgm commented Nov 12, 2026 •

Copy link
Copy Markdown

A source file is previewed as one block of plain text: Space shows it in a single ink, and so do its opening lines in the details pane. With these two commits both draw it in color, in the colors of the theme in use. The colors are read by bat, which Omarchy already installs (omarchy-base.packages), run with its ansi theme so that it names six terminal colors and nothing else, and Folio draws those six in the current theme's red, green, yellow, blue, magenta and cyan. The suite goes from 196 to 202 tests. No library is linked and nothing is added to the build; where bat isn't installed a source file is shown as it is today.

What you'd notice

  • Space on a source file shows it in color. Comments and strings, keywords, function names and numbers each get the ink bat gives them, for every language bat knows.
  • The details pane's opening lines are in the same colors. They are the same lines, wrapped and cut at the same places, with their spaces and tabs as wide as before.
  • The colors are the theme's. The six inks are the six colors of the theme's own colors.toml. Picking another theme recolors an open preview and the details at once.
  • Every ink can be read. A theme color too close to the background it is drawn on (under 4.5:1 against the nearer of the two backgrounds code is drawn on) is moved toward black or white only as far as 4.5:1 takes, keeping its hue. Of the 23 stock themes, 12 have at least one of the six under that on their own background, the lowest at 2.05:1; a color that already reads is drawn exactly as the theme gives it.
  • The text and its colors arrive together. The preview never shows a file plain and then colors it: the text is shown once, with its colors. For a long file that means its opening (400 lines, or as many whole lines as fit in 16 KiB, counted in the bytes bat is sent); the lines after it get their colors when bat has read the whole text, and nothing but the ink changes when they do.
  • A plain text and a Markdown file are shown as before. bat isn't run for them, in the preview or in the details.

Pictures

A mini PC, the same folder, main on the left and this branch on the right.

A Python file in the preview before and after

A C file in the preview before and after

The opening lines of a Python file in the details before and after, at twice their size

The same file on three stock themes, one of them light, main above and this branch below.

A Python file in the preview on Catppuccin Latte, Rose Pine and Miasma, before and after

What it costs

bat is run once for a source file that is previewed, a second time for one that goes on past its opening, and once for the 41 lines the details pane shows, always off the UI thread. A plain text and a Markdown file wait for nothing. On a mini PC that was otherwise idle (load 0.7), 25 runs of bat each, as Folio runs it:

Text Median Fastest to slowest
40 lines of Python 12.9 ms 12.1 to 47.9 ms
400 lines 27.2 ms 26.4 to 33.1 ms
4,000 lines, 84 KiB 169.9 ms 162.3 to 249.0 ms

So a source file's text appears 13 to 27 ms later than on main, already in color, and the lines of a 4,000 line file past the first 400 get theirs about 170 ms after that. Long lines are why the opening is also held to 16 KiB: one line of minified JavaScript takes bat 23 ms at 4 KiB, 33 ms at 8 KiB and 50 ms at 16 KiB (the same mini PC, load 0.01, three runs each). A text whose first line is longer than that is shown at once and colored by the one run over the whole text. A run is given up on after half a second for the opening and five seconds for a whole text, and one for a whole text is stopped as soon as another file is shown or the preview is closed.

On the UI thread, measured on a Linux server with a 128 KiB text of 2,721 lines, six runs: showing the text with its first 400 lines colored takes 16.9 to 19.0 ms, against 14.4 to 16.6 ms for the plain text; the colors of the remaining lines are then applied in one step of 27.9 to 31.0 ms. (Applying them line by line with QSyntaxHighlighter::rehighlight() took 537 to 552 ms, which is why they aren't.)

What stays the same

  • Without bat, with one that fails, or with one that hasn't answered in half a second, the text is shown plain, as on main. One that prints far more than colors could take is stopped, or left unread when it has already ended, and what it prints on its standard error is never kept.
  • bat is run with --no-config: a pager, line numbers or a theme in the user's own bat settings can't change what is shown. It reads the text Folio has already read, on its standard input, so no file is opened a second time and the preview's 128 KiB limit holds.
  • A line is colored only where the text on screen is the line bat read. If the two ever differ, that line stays plain.
  • The details pane lays its lines out exactly as it did: the same number of lines, the same width and the same height, which the test compares against the plain text, tabs and Windows line ends included.
  • The theme gains green, read from colors.toml like the other colors with a fallback beside theirs, and codeInks, the six as code is drawn in them. No other color of the theme changes.

Tests

Six new cases, all of which fail on the sources of main:

  • codeColorsReadWhatBatPrints: the escape sequences bat prints become runs of the six inks, an ink carries across a line end, bright codes count as their plain ones, black, white and a reset end an ink, and colors by number and sequences that aren't colors are passed over.
  • codeColorsPaintTheLinesTheyWereReadFrom: a real TextEdit is colored in the given inks, takes another theme's inks at once, leaves a line plain when the text has moved on, handles Windows line ends, and tells the text's layout of new colors once, not line by line.
  • previewerColorsCode: with a stand-in bat, the text and its colors arrive in one change; a plain text and a Markdown file never run it; a long file shows its opening colored and gets the rest with no change to the text; 400 lines are run once and a 401st makes it two; long lines cut the opening at 16 KiB, counted in bytes, so sooner for letters of three bytes, and a first line longer than that isn't waited for; a file stepped past before it was read isn't given to bat; a run on a whole text is stopped when another file is shown, even when the first is shown again right after, or when the preview is closed, and colors that arrive for a file no longer shown are dropped; a missing, failing, stuck or endlessly printing bat, or one that prints too much and ends at once, leaves plain text, a stuck one long before the five seconds a whole text is given.
  • previewWindowDrawsCodeInTheThemesInks: the real PreviewWindow.qml draws a C file's words in the theme's magenta and green, and in another theme's as soon as it is picked.
  • detailsColorTheOpeningLinesOfCode: the details carry the colors with the text in one change and lose them when the same file is read again without bat; a plain text and a Markdown file never run it; a bat that never answers holds the lines back half a second at most; a real PreviewPane draws them with the same line count, width and height as the plain text, tabs and Windows line ends included, and in another theme's colors as soon as it is picked.
  • themeDrawsCodeInInksThatReadOnItsBackgrounds: a theme whose six colors read is drawn in exactly those; a yellow too faint for a light theme is darkened and a red too deep for a dark one lightened, each to 4.5:1 against the nearer background and no further, with its hue kept.

91 single changes to the sources (a limit, a bound, a missing check, a swapped ink) were each tried alone, and each made one of these six cases fail: 89 by a failed check, one by a run that never ended and one by a crash. Each commit builds without warnings and passes the suite on its own, also with TMPDIR set to a folder whose name has a space, where only extractRefusesWhatWouldLandOutside fails, as it does on main.

@greptile-apps

greptile-apps Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; all three previous findings are fixed.

Summary

Adds theme-colored source previews through optional bat runs.

  • Source previews show syntax colors in the active theme.
  • The details pane colors a source file’s opening lines.
  • Code colors stay readable against the active theme.

Review used source inspection; tests were not run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  File[Bounded source text] --> Opening[Color opening with bat]
  Opening --> Preview[Show text and opening colors]
  Preview --> Rest[Color remaining lines]
  Rest --> Paint[Update colors only]
  Theme[Current theme] --> Preview
  Theme --> Paint
  Opening --> Details[Show details text and colors]
Loading

Reviews (2) · Last reviewed commit: "Color the opening lines of code in the d..." · Reviewed by Greptile

Comment thread src/backend.cpp Resolved
Comment thread src/codecolors.cpp Resolved
Comment thread src/previewer.cpp Resolved
A source file was previewed as plain text. Its lines now come
in the theme's colors, as bat reads them: the first 400 with
the text, a longer file's others once bat is through it.
Without bat the text is shown as it was.
The details showed a source file's first lines as plain text.
They now come in the theme's colors, read with the text and
laid out as the plain lines are. Without bat nothing changes.
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