mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-21 05:52:35 +08:00
fix(jetbrains): underline prompt attachment file links
Remove the remaining prompt attachment strip border and reuse the shared underlined file-link styling for attachment chip labels so clickable files look consistent in the transcript.
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
package ai.kilocode.client.session.ui
|
||||
|
||||
import com.intellij.xml.util.XmlStringUtil
|
||||
|
||||
internal fun fileLinkText(value: String): String = value.lineSequence()
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotEmpty() }
|
||||
.joinToString(" ")
|
||||
|
||||
internal fun fileLinkHtml(value: String): String {
|
||||
val text = fileLinkText(value)
|
||||
if (text.isBlank()) return ""
|
||||
return XmlStringUtil.wrapInHtml("<nobr><u>${XmlStringUtil.escapeString(text)}</u></nobr>")
|
||||
}
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package ai.kilocode.client.session.ui.attachment
|
||||
|
||||
import ai.kilocode.client.plugin.KiloBundle
|
||||
import ai.kilocode.client.session.ui.fileLinkHtml
|
||||
import ai.kilocode.client.session.ui.style.SessionUiStyle
|
||||
import ai.kilocode.client.ui.UiStyle
|
||||
import ai.kilocode.client.ui.iconButton
|
||||
@@ -68,7 +69,7 @@ class AttachmentChip(
|
||||
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)
|
||||
toolTipText = tip
|
||||
accessibleContext?.accessibleName = KiloBundle.message("prompt.attachment.open", item.name)
|
||||
val label = JBLabel(label()).apply {
|
||||
val label = JBLabel(fileLinkHtml(label())).apply {
|
||||
icon = attachmentIcon(item.mime, item.name)
|
||||
iconTextGap = JBUI.scale(SessionUiStyle.View.Attachment.CHIP_ICON_GAP)
|
||||
toolTipText = tip
|
||||
|
||||
+3
-2
@@ -27,8 +27,9 @@ class PromptAttachmentView(
|
||||
private val cards = LinkedHashMap<String, JComponent>()
|
||||
private val row = Stack.horizontal(gap = UiStyle.Gap.sm())
|
||||
private val scroll = JBScrollPane(row).apply {
|
||||
border = null
|
||||
viewportBorder = null
|
||||
// Empty borders remove the visible scroll pane frame; null can be replaced by the current UI.
|
||||
border = JBUI.Borders.empty()
|
||||
viewportBorder = JBUI.Borders.empty()
|
||||
isOpaque = false
|
||||
viewport.isOpaque = false
|
||||
horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
|
||||
|
||||
+6
-9
@@ -7,6 +7,8 @@ import ai.kilocode.client.session.SessionFileOpener
|
||||
import ai.kilocode.client.session.model.Tool
|
||||
import ai.kilocode.client.session.model.ToolExecState
|
||||
import ai.kilocode.client.session.model.ToolKind
|
||||
import ai.kilocode.client.session.ui.fileLinkHtml
|
||||
import ai.kilocode.client.session.ui.fileLinkText
|
||||
import ai.kilocode.client.session.ui.selection.SessionSelection
|
||||
import ai.kilocode.client.session.ui.selection.SessionCopyTarget
|
||||
import ai.kilocode.client.session.ui.style.SessionEditorStyle
|
||||
@@ -135,8 +137,8 @@ class FileLinkLabel(
|
||||
|
||||
@RequiresEdt
|
||||
fun setTarget(path: String?, text: String): Boolean {
|
||||
val next = single(text.ifBlank { path.orEmpty() })
|
||||
val value = if (next.isBlank()) "" else XmlStringUtil.wrapInHtml("<nobr><u>${XmlStringUtil.escapeString(next)}</u></nobr>")
|
||||
val next = fileLinkText(text.ifBlank { path.orEmpty() })
|
||||
val value = fileLinkHtml(next)
|
||||
var changed = false
|
||||
if (href != path) {
|
||||
href = path
|
||||
@@ -489,7 +491,7 @@ internal fun setText(label: JBLabel, text: String): Boolean {
|
||||
|
||||
@RequiresEdt
|
||||
internal fun setTargetText(label: JBLabel, text: String): Boolean {
|
||||
val value = single(text)
|
||||
val value = fileLinkText(text)
|
||||
if (label.text == value) return false
|
||||
label.text = value
|
||||
return true
|
||||
@@ -511,16 +513,11 @@ private fun <T : JBLabel> clip(label: T): T = label.apply {
|
||||
}
|
||||
|
||||
private fun html(text: String): String {
|
||||
val value = single(text)
|
||||
val value = fileLinkText(text)
|
||||
if (value.isBlank()) return ""
|
||||
return XmlStringUtil.wrapInHtml("<nobr>${XmlStringUtil.escapeString(value)}</nobr>")
|
||||
}
|
||||
|
||||
private fun single(text: String): String = text.lineSequence()
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotEmpty() }
|
||||
.joinToString(" ")
|
||||
|
||||
@RequiresEdt
|
||||
internal fun show(parts: ToolParts, link: Boolean): Boolean {
|
||||
var changed = false
|
||||
|
||||
+1
-1
@@ -383,7 +383,7 @@ class SessionUiUpdateTest : BasePlatformTestCase() {
|
||||
val chip = find(view, AttachmentChip::class.java)
|
||||
|
||||
assertNotNull(chip)
|
||||
assertTrue(findAll(chip!!, JBLabel::class.java).any { it.text == "HvJwtFilter.java:12-40" })
|
||||
assertTrue(findAll(chip!!, JBLabel::class.java).any { it.text.contains("<u>HvJwtFilter.java:12-40</u>") })
|
||||
}
|
||||
|
||||
fun `test source backed image attachment still renders in prompt strip`() {
|
||||
|
||||
+30
-2
@@ -5,6 +5,8 @@ import ai.kilocode.client.session.ui.attachment.AttachmentCardItem
|
||||
import ai.kilocode.client.session.ui.attachment.AttachmentChip
|
||||
import ai.kilocode.client.ui.UiStyle
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import java.awt.Container
|
||||
|
||||
class PromptAttachmentViewTest : BasePlatformTestCase() {
|
||||
// The attachment strip should line up with the prompt text horizontally and keep only a
|
||||
@@ -22,8 +24,14 @@ class PromptAttachmentViewTest : BasePlatformTestCase() {
|
||||
fun `test attachment scroll pane has no border line`() {
|
||||
val scroll = PromptAttachmentView("m1") {}.scrollPane()
|
||||
|
||||
assertNull(scroll.border)
|
||||
assertNull(scroll.viewportBorder)
|
||||
assertEquals(0, scroll.border.getBorderInsets(scroll).top)
|
||||
assertEquals(0, scroll.border.getBorderInsets(scroll).left)
|
||||
assertEquals(0, scroll.border.getBorderInsets(scroll).bottom)
|
||||
assertEquals(0, scroll.border.getBorderInsets(scroll).right)
|
||||
assertEquals(0, scroll.viewportBorder.getBorderInsets(scroll).top)
|
||||
assertEquals(0, scroll.viewportBorder.getBorderInsets(scroll).left)
|
||||
assertEquals(0, scroll.viewportBorder.getBorderInsets(scroll).bottom)
|
||||
assertEquals(0, scroll.viewportBorder.getBorderInsets(scroll).right)
|
||||
}
|
||||
|
||||
// With the outline removed, the chip owns no internal padding; alignment comes from the
|
||||
@@ -41,4 +49,24 @@ class PromptAttachmentViewTest : BasePlatformTestCase() {
|
||||
assertEquals(0, chip.top)
|
||||
assertEquals(0, chip.bottom)
|
||||
}
|
||||
|
||||
fun `test attachment chip uses file link underline style`() {
|
||||
val chip = AttachmentChip(
|
||||
AttachmentCardItem("HvJwtFilter.java", "text/plain", "file:///HvJwtFilter.java"),
|
||||
file = true,
|
||||
startLine = 40,
|
||||
endLine = 42,
|
||||
)
|
||||
val label = components(chip).filterIsInstance<JBLabel>().single()
|
||||
|
||||
assertTrue(label.text.contains("<u>HvJwtFilter.java:40-42</u>"))
|
||||
}
|
||||
|
||||
private fun components(root: Container): List<java.awt.Component> = buildList {
|
||||
fun visit(comp: java.awt.Component) {
|
||||
add(comp)
|
||||
if (comp is Container) comp.components.forEach { visit(it) }
|
||||
}
|
||||
visit(root)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user