fix(jetbrains): linkify urls inside inline code#13551
Conversation
CommonMark's autolink extension skips code spans, so a URL written in backticks rendered as inert text in chat messages while bare URLs became links. Extend the post-render pass in MdCommon that already linkifies file references so it also wraps http(s) URLs, giving them link color, underline, hover, and click handling inside inline code.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (5 files)
Previous Review Summary (commit 1d6744e)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 1d6744e)Status: No Issues Found | Recommendation: Merge Files Reviewed (4 files)
Reviewed by grok-4.6 · Input: 144.5K · Output: 12.9K · Cached: 311.4K Review guidance: REVIEW.md from base branch |
| } | ||
|
|
||
| /** Trims a raw URL match down to the part that belongs to the link. */ | ||
| private fun cut(value: String): String { |
There was a problem hiding this comment.
Isn't there a standard lib for that?
There was a problem hiding this comment.
Yes — org.nibor.autolink is already the scanner behind CommonMark’s AutolinkExtension. I replaced the custom regex/cut() boundary logic with LinkExtractor over raw Code AST literals, so punctuation, bracket balancing, quote/control-character boundaries, Unicode whitespace, and escaping all come from the library/CommonMark renderer. Updated in 46a885c.
I also made org.nibor.autolink:autolink:0.12.0 an explicit pinned implementation dependency rather than relying on the transitive edge or the IDE classpath. ./gradlew buildPlugin succeeds, and the resulting ZIP contains kilo.jetbrains/lib/autolink-0.12.0.jar.
Replace the custom URL boundary and bracket trimming logic with the same org.nibor.autolink scanner used by CommonMark's autolink extension. Run it against raw inline-code AST literals so HtmlWriter owns escaping, and declare the dependency explicitly so Gradle bundles it with the plugin.
Issue
No issue filed; reported directly while reviewing a JetBrains release report where every URL was unclickable.
Context
In the JetBrains chat transcript,
http/httpsURLs written inside backticks render as inert text — no hover, no cursor change, no click. Agents routinely emit URLs as inline code (release reports, PR links, run URLs), so a large share of the links a user sees in the JetBrains plugin are dead.The link plumbing itself was fine. The gap is that CommonMark's
AutolinkExtensiononly visits text nodes, never code spans, so`https://…`never becomes an anchor. Bare URLs already worked end to end.Implementation
The HTML renderer now overrides CommonMark's core
Codenode renderer. It runsorg.nibor.autolink.LinkExtractorover each raw inline-code literal and emits anchors forhttp/httpsspans beforeHtmlWriterescapes their text and attributes. This is the same URL scanner used by CommonMark's existing autolink extension, so trailing punctuation, balanced brackets, quote boundaries, control characters, and Unicode whitespace follow the library's tested behavior instead of custom URL parsing.Only
httpandhttpsmatches become links.LinkType.URLcan detect anyscheme://…, while the session link router sends non-file schemes to the browser; filtering here preventsfile,ftp, or other schemes from being routed incorrectly.org.nibor.autolink:autolink:0.12.0is declared explicitly as animplementationdependency in the frontend module and pinned in the version catalog. We do not rely on an IntelliJ-bundled classpath or on CommonMark's transitive dependency edge.buildPluginpackages it askilo.jetbrains/lib/autolink-0.12.0.jarin the distributable ZIP.MdCommononly retains the CSS rule for the generatedkilo-url-refanchors: standard IDE link color and underline while preserving the inline-code monospace font. Existing click handling remains unchanged (MdView.LinkEvent→openSessionLink→BrowserUtil.browse), and fenced code remains on the separate editor/code-block rendering path.Screenshots / Video
N/A — the visual delta is that an inline-code URL picks up the standard IDE link color and underline; there is no new UI surface. Behavior is asserted in tests against the rendered
HTMLDocument.How to Test
Manual/local verification
./gradlew testfrompackages/kilo-jetbrains/— passed (executed by the agent)./gradlew typecheckfrompackages/kilo-jetbrains/— passed (executed by the agent)./gradlew buildPluginfrompackages/kilo-jetbrains/— passed (executed by the agent)build/distributions/kilo.jetbrains-7.1.0.zip; it containskilo.jetbrains/lib/autolink-0.12.0.jar(executed by the agent)MdViewTest(executed by the agent): a code-span URL produces<a class="kilo-url-ref">plus the matching CSS rule; query separators survive in the href; trailing punctuation and unbalanced brackets stay outside the link; balanced brackets stay inside; URL scanning stops at characters that cannot appear in a URL; autolinked and markdown-link URLs are not wrapped a second time; fenced-code URLs are not linkified; a URL followed by a file reference produces both link kinds.MdViewHybridTest(executed by the agent): the renderedHTMLDocumentcontains a liveAelement with the expectedhref, and activating it dispatches anMdView.LinkEvent.Reviewer test steps
./gradlew runIdefrompackages/kilo-jetbrains/Release PR: `https://github.com/Kilo-Org/kilocode/pull/13524`[text](url)link still behave as beforeBlocked checks and substitute verification
Checklist
Get in Touch
N/A