Thin the app's comments

The same pass the server had, on the Kotlin side: comments restating what
the code says are gone, and the ones recording a measurement, a constraint
or an incident are kept but cut to a few lines each. 6540 comment lines to
5674, and 920 lines off the app.

Two doc comments had drifted onto the item above the one they describe --
`contextAfter`'s onto `sessionWorking` in Events.kt, and `UsageMonitor`'s
equivalent on the server was fixed in the previous commit. Each is back on
its own item, which is the only non-comment line this diff moves.

The comments are reflowed to the column limit at their own indentation:
several were written wide, and ktfmt re-wrapped them into lines holding a
single orphan word. `/tmp` script, not kept -- ktfmt is idempotent over the
result, which is the check.

Left alone deliberately: this codebase's remaining comment density is high
because the comments carry things the code cannot say -- what a null means,
what a number was measured against, which bug a guard exists for. Of the
238 one-line doc comments in the app, five were pure restatement of the
name and were removed; the rest each say something the signature does not.

ktfmtFormat, compileDebugKotlin, lintDebug and testDebugUnitTest pass;
cargo test (127), clippy --all-targets and fmt still clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-04 16:20:16 -04:00
1 parent 79682f03a7
commit edc39c7371
68 files changed
+2077 -2997

No files matched your search

@@ -12,10 +12,8 @@ import androidx.compose.ui.text.buildAnnotatedString
* and again on every recomposition.
*
* Why per line at all: the viewer is a `LazyColumn` of lines rather than one `Text`, because text
* layout is linear in the text and a twenty-thousand-line file in one `Text` measures all of it to
* draw a screenful. That means each row needs *its* colours, and the scanner answers in offsets
* into the whole file -- so the spans are bucketed here, once, in one pass over an already-ordered
* list, rather than each row searching the whole list for the part that is its.
* layout is linear in the text. That means each row needs *its* colours, and the scanner answers in
* offsets into the whole file -- so the spans are bucketed here, once, in one pass.
*/
class FileLines
private constructor(
@@ -37,11 +35,9 @@ private constructor(
get() = lines.size
/**
* One line, coloured.
*
* Built when the row is composed rather than up front: a file has far more lines than a screen
* shows, and an `AnnotatedString` per line for all of them is the cost the lazy list exists to
* avoid.
* One line, coloured. Built when the row is composed rather than up front: a file has far more
* lines than a screen shows, and an `AnnotatedString` per line for all of them is the cost the
* lazy list exists to avoid.
*/
fun line(index: Int): AnnotatedString {
val text = lines[index]
@@ -60,16 +56,13 @@ private constructor(
*
* Exactly one trailing newline is dropped before splitting, so a file that ends the way
* text files are supposed to end has the number of lines its author would count -- `wc -l`
* agrees, and so does every editor. Without that, every well-formed file gained a phantom
* empty last line, which is a wrong line number on every file in the repository. An empty
* file is one empty line numbered 1, which is what it is: a file with nothing in it still
* has somewhere for a cursor to go.
* agrees. Without that, every well-formed file gained a phantom empty last line. An empty
* file is one empty line numbered 1, which is what it is.
*/
fun of(text: String, language: Language?): FileLines =
// Timed, and always, for the same reason everything else here is: the cost of opening
// a large file is the number that decides whether the server's size limit is right,
// and an instrument that is only in the build nobody is running answers nothing. It
// lands in the render report beside the transcript's own figures.
// Timed, and always, for the reason everything else here is: the cost of opening a
// large file is the number that decides whether the server's size limit is right, and
// an instrument that is only in the build nobody is running answers nothing.
DebugStats.timed("file scanned and cut into lines") {
val body = text.removeSuffix("\n")
val lines = body.split('\n')
@@ -80,10 +73,9 @@ private constructor(
/**
* How many columns a line occupies.
*
* A tab counts as eight rather than as one, and deliberately upwards: this decides how far
* the viewer can scroll, and over-estimating leaves a little empty space past the longest
* line where under-estimating makes the end of that line unreachable. Compose draws a tab
* as a single advance, so eight is the generous reading rather than the accurate one.
* A tab counts as eight rather than one, and deliberately upwards: this decides how far the
* viewer can scroll, and over-estimating leaves a little empty space past the longest line
* where under-estimating makes the end of that line unreachable.
*/
private fun columnsOf(line: String): Int {
var count = 0
@@ -95,10 +87,9 @@ private constructor(
* The scanner's spans, in file offsets, as spans per line in line offsets.
*
* One walk down both lists, which is what the scanner's guarantee buys: its spans come out
* ordered, non-overlapping and inside the text, so a span can only belong to the line the
* walk has reached or to ones after it. A span crossing a line break -- a block comment, a
* multi-line string -- is cut at each break and appears in each line it covers, because a
* row is drawn on its own and cannot inherit a colour from the row above.
* ordered, non-overlapping and inside the text. A span crossing a line break is cut at each
* break and appears in each line it covers, because a row is drawn on its own and cannot
* inherit a colour from the row above.
*/
private fun bucket(lines: List<String>, spans: List<Span>): List<List<Span>> {
val out = ArrayList<List<Span>>(lines.size)