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:
1 parent
79682f03a7
commit
edc39c7371
68 files changed
+2077
-2997
No files matched your search
@@ -7,23 +7,19 @@ package com.example.aiapp
|
||||
* Its own scanner rather than a row of [Rules] because markdown has neither keywords nor strings:
|
||||
* what a character means depends on where it sits. A `#` opens a heading at the start of a line and
|
||||
* is an ordinary character three words in; a `*` opens emphasis only if something closes it on the
|
||||
* same line. The token scanner cannot ask either question, and answering them with its rules is how
|
||||
* a highlighter comes to grey out the second half of a paragraph.
|
||||
* same line. The token scanner cannot ask either question.
|
||||
*
|
||||
* Structure is read a line at a time and each line's prose is then read left to right, so every
|
||||
* decision is made inside one line -- except the two things that are not one line. A fenced block
|
||||
* is state carried forward, so an unclosed fence colours the rest of the text, which is also what
|
||||
* it looks like while somebody is still writing it. A table is found by its delimiter row
|
||||
* (`|---|---|`), which is the only line of one that cannot be anything else, and its header is the
|
||||
* line before that -- the one place here that looks ahead.
|
||||
* Structure is read a line at a time and each line's prose left to right, so every decision is made
|
||||
* inside one line -- except the two that are not. A fenced block is state carried forward, so an
|
||||
* unclosed fence colours the rest of the text, which is what it looks like while somebody is
|
||||
* writing it. A table is found by its delimiter row (`|---|---|`), the only line of one that cannot
|
||||
* be anything else, and its header is the line before that -- the one place here that looks ahead.
|
||||
*
|
||||
* What is deliberately *not* recognised: an indented code block. Four spaces after a blank line is
|
||||
* one, and four spaces after a bullet is a list item's second paragraph, and the two are told apart
|
||||
* by what came before rather than by the line itself. Colouring the wrong one of those as code is a
|
||||
* mistake the reader cannot see, so both are left plain, which is the safe answer.
|
||||
* one, four spaces after a bullet is a list item's second paragraph, and the two are told apart by
|
||||
* what came before. Colouring the wrong one as code is a mistake the reader cannot see.
|
||||
*
|
||||
* Like [scan], the spans come out ordered, non-overlapping and inside the text by construction:
|
||||
* every one is emitted by a pass that only moves forward, and nothing here throws.
|
||||
* Like [scan], the spans come out ordered, non-overlapping and inside the text by construction.
|
||||
*/
|
||||
fun scanMarkdown(code: String): List<Span> = MarkdownScanner(code).run()
|
||||
|
||||
@@ -36,7 +32,7 @@ private const val RULE_MARKERS = "-*_="
|
||||
/** The characters that can open emphasis, strong emphasis or a strikethrough. */
|
||||
private const val EMPHASIS = "*_~"
|
||||
|
||||
/** Characters that end a bare URL wherever they appear in it, and ones only trimmed off the end. */
|
||||
/** Characters that end a bare URL wherever they appear, and ones only trimmed off the end. */
|
||||
private const val URL_STOPS = "<>\"'`|"
|
||||
private const val URL_TRAILING = ".,:;!?"
|
||||
|
||||
@@ -53,8 +49,8 @@ private class MarkdownScanner(private val code: String) {
|
||||
val end = lineEnd(at)
|
||||
val open = fence
|
||||
if (open != null) {
|
||||
// The content and the closing line alike: a fence is one block of code, and its
|
||||
// own delimiters belong to it the way a string's quotes belong to the string.
|
||||
// The content and the closing line alike: a fence is one block of code, and its own
|
||||
// delimiters belong to it the way a string's quotes belong to the string.
|
||||
emit(at, end, Kind.STRING)
|
||||
if (closesFence(at, end, open)) fence = null
|
||||
} else {
|
||||
@@ -77,11 +73,10 @@ private class MarkdownScanner(private val code: String) {
|
||||
/**
|
||||
* One line that is not inside a fence, and whether the table it may be part of is still open.
|
||||
*
|
||||
* A table is recognised by its delimiter row (`|---|---|`), which is the only line of one that
|
||||
* cannot be anything else. That row comes *after* the header it belongs to, so the header is
|
||||
* found by looking one line ahead -- the single piece of lookahead here, and cheaper than the
|
||||
* alternative of colouring every `|` in the document, which would mark the pipes in a shell
|
||||
* command written in a paragraph.
|
||||
* A table is recognised by its delimiter row, the only line of one that cannot be anything
|
||||
* else. That row comes *after* the header it belongs to, so the header is found by looking one
|
||||
* line ahead -- the single piece of lookahead here, and cheaper than colouring every `|` in the
|
||||
* document, which would mark the pipes in a shell command written in a paragraph.
|
||||
*/
|
||||
private fun row(start: Int, end: Int, table: Boolean): Boolean {
|
||||
if (tableDelimiter(start, end)) {
|
||||
@@ -142,10 +137,9 @@ private class MarkdownScanner(private val code: String) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Spans, coalesced with the one before when they touch and agree.
|
||||
*
|
||||
* Worth doing here rather than leaving it to the caller: the line scanner emits per marker and
|
||||
* per word, so a heading would otherwise arrive as a dozen abutting spans of one colour.
|
||||
* Spans, coalesced with the one before when they touch and agree. Worth doing here rather than
|
||||
* leaving it to the caller: the line scanner emits per marker and per word, so a heading would
|
||||
* otherwise arrive as a dozen abutting spans of one colour.
|
||||
*/
|
||||
private fun emit(start: Int, end: Int, kind: Kind) {
|
||||
if (end <= start) return
|
||||
@@ -179,17 +173,16 @@ private class MarkdownScanner(private val code: String) {
|
||||
private fun opensFence(start: Int, end: Int): String? {
|
||||
val run = fenceRun(start, end) ?: return null
|
||||
emit(run.first, run.last + 1, Kind.STRING)
|
||||
// The info word is what the fence is a fence *of*, which is metadata about the block
|
||||
// rather than part of it -- the same reading as a Rust attribute above a struct.
|
||||
// The info word is what the fence is a fence *of*, which is metadata about the block rather
|
||||
// than part of it.
|
||||
emit(indented(run.last + 1, end), end, Kind.METADATA)
|
||||
return code.substring(run.first, run.last + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this line closes a fence opened by [open].
|
||||
*
|
||||
* The same character, at least as many of them, and nothing else on the line -- so a longer run
|
||||
* closes a shorter one and a line of backticks with a word after it does not close anything.
|
||||
* Whether this line closes a fence opened by [open]: the same character, at least as many of
|
||||
* them, and nothing else on the line -- so a longer run closes a shorter one and a line of
|
||||
* backticks with a word after it does not close anything.
|
||||
*/
|
||||
private fun closesFence(start: Int, end: Int, open: String): Boolean {
|
||||
val run = fenceRun(start, end) ?: return false
|
||||
@@ -227,10 +220,9 @@ private class MarkdownScanner(private val code: String) {
|
||||
* A line made of one repeated rule character and nothing else.
|
||||
*
|
||||
* `---`, `***` and `___` are thematic breaks; `===` and `---` are also the underline of a
|
||||
* setext heading. The two are the same line to look at and mean the same thing to a reader -- a
|
||||
* rule drawn across the page -- so they get one appearance rather than a lookback to tell them
|
||||
* apart. One `=` is enough because a setext underline may be a single character; a break needs
|
||||
* three, which is what keeps a `- ` bullet out of here.
|
||||
* setext heading. The two are the same line to look at and mean the same thing to a reader, so
|
||||
* they get one appearance rather than a lookback. One `=` is enough because a setext underline
|
||||
* may be a single character; a break needs three, which keeps a `- ` bullet out of here.
|
||||
*/
|
||||
private fun thematicBreak(start: Int, end: Int): Boolean {
|
||||
val marker = code[start]
|
||||
@@ -292,10 +284,9 @@ private class MarkdownScanner(private val code: String) {
|
||||
}
|
||||
|
||||
/**
|
||||
* `` `code` ``, closed by a run of exactly as many backticks as opened it.
|
||||
*
|
||||
* That count is what lets a span hold a backtick of its own (``` ``a ` b`` ```), and it is why
|
||||
* the search skips over a shorter or longer run rather than stopping at the first backtick.
|
||||
* `` `code` ``, closed by a run of exactly as many backticks as opened it. That count is what
|
||||
* lets a span hold a backtick of its own, and why the search skips over a shorter or longer run
|
||||
* rather than stopping at the first backtick.
|
||||
*/
|
||||
private fun codeSpan(start: Int, end: Int): Int {
|
||||
var open = start
|
||||
@@ -323,9 +314,8 @@ private class MarkdownScanner(private val code: String) {
|
||||
* `[text](destination)`, and the same with a leading `!` for an image.
|
||||
*
|
||||
* The text is drawn as prose -- it is what the reader reads -- so only the brackets around it
|
||||
* are marked, and the destination is metadata: the place the link goes rather than anything
|
||||
* said to the reader. A `[text]` with no destination after it is left plain, because that is
|
||||
* what a reference link and a bracketed aside look like, and neither is worth guessing at.
|
||||
* are marked, and the destination is metadata. A `[text]` with no destination after it is left
|
||||
* plain, because that is what a reference link and a bracketed aside look like.
|
||||
*/
|
||||
private fun link(start: Int, bracket: Int, end: Int): Int {
|
||||
var depth = 0
|
||||
@@ -357,8 +347,7 @@ private class MarkdownScanner(private val code: String) {
|
||||
* `<https://example.com>` and `<name@example.com>`, drawn as the destination they are.
|
||||
*
|
||||
* The angle brackets have to hold no whitespace and something that makes an address of it -- a
|
||||
* scheme's colon or an at sign -- which is what keeps an HTML tag out: `<div>` has neither, and
|
||||
* `<img src="http://x">` has the colon but also a space.
|
||||
* scheme's colon or an at sign -- which is what keeps an HTML tag out.
|
||||
*/
|
||||
private fun autolink(start: Int, end: Int): Int {
|
||||
var at = start + 1
|
||||
@@ -380,13 +369,12 @@ private class MarkdownScanner(private val code: String) {
|
||||
/**
|
||||
* A bare `scheme://…` written in prose, or null if one does not start here.
|
||||
*
|
||||
* A scheme and `://` rather than a list of them, so `ftp`, `file` and `ssh` need no entry, and
|
||||
* the pair of colons is what makes the match unambiguous enough to draw without a closer.
|
||||
* A scheme and `://` rather than a list of them, so `ftp`, `file` and `ssh` need no entry.
|
||||
*
|
||||
* Where it ends is the part worth stating: the sentence's punctuation is not the address, so a
|
||||
* trailing `.` or `,` is given back, and so is a closing bracket unless one opened inside the
|
||||
* URL -- otherwise a link in parentheses loses its `)` to the address. A pipe stops it too,
|
||||
* because a URL in a table cell must not swallow the cell's edge.
|
||||
* URL -- otherwise a link in parentheses loses its `)`. A pipe stops it too, because a URL in a
|
||||
* table cell must not swallow the cell's edge.
|
||||
*/
|
||||
private fun url(start: Int, end: Int): Int? {
|
||||
if (start > 0 && isWord(code[start - 1])) return null
|
||||
@@ -415,14 +403,13 @@ private class MarkdownScanner(private val code: String) {
|
||||
}
|
||||
|
||||
/**
|
||||
* `*emph*`, `**strong**`, `_emph_` and `~~struck~~`, drawn markers and all.
|
||||
* `*emph*`, `**strong**`, `_emph_` and `~~struck~~`, drawn markers and all -- which is how the
|
||||
* token scanner draws a string: the quotes are part of the thing.
|
||||
*
|
||||
* Markers and all because that is how the token scanner draws a string: the quotes are part of
|
||||
* the thing. The two guards are what keep this off code that happens to be in a paragraph --
|
||||
* the opener must be followed by something to emphasise and the closer preceded by something
|
||||
* emphasised, so `a * b * c` opens nothing and neither does the `*p = *q` of a C fragment.
|
||||
* Underscores additionally may not start or end inside a word, or every `snake_case_name` in a
|
||||
* document would be half emphasised.
|
||||
* The two guards keep this off code that happens to be in a paragraph: the opener must be
|
||||
* followed by something to emphasise and the closer preceded by something emphasised, so `a * b
|
||||
* * c` opens nothing and neither does the `*p = *q` of a C fragment. Underscores may not start
|
||||
* or end inside a word, or every `snake_case_name` would be half emphasised.
|
||||
*/
|
||||
private fun emphasis(start: Int, end: Int): Int {
|
||||
val marker = code[start]
|
||||
|
||||
Reference in new issue
Block a user