fix(jetbrains): show absolute reverted file tooltips

This commit is contained in:
kirillk
2026-08-03 15:44:25 -04:00
parent 9b4738ee55
commit 6eba817857
2 changed files with 53 additions and 3 deletions
@@ -24,7 +24,11 @@ import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
import com.intellij.util.ui.components.BorderLayoutPanel
import java.awt.BorderLayout
import java.awt.Component
import java.awt.Container
import java.awt.Dimension
import java.nio.file.Path
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.ScrollPaneConstants
@@ -133,7 +137,7 @@ class RevertBanner(
val row = rows.getOrPut(item.file) {
Row(item)
}
row.update(item, names[item.file] ?: item.file)
row.update(item, names[item.file] ?: item.file, absolute(item.file))
row.panel
}
if (files.components.toList() != order) {
@@ -188,6 +192,15 @@ class RevertBanner(
openDiff(diffs, KiloBundle.message("revert.banner.openDiff.title"), "revert:${sessionId ?: "pending"}:${revert.messageID}")
}
private fun absolute(file: String): String {
val path = runCatching { Path.of(file) }.getOrNull() ?: return file
if (path.isAbsolute) return path.normalize().toString()
val root = model.session?.directory
?.takeIf { it.isNotBlank() }
?.let { runCatching { Path.of(it) }.getOrNull() }
return (root?.resolve(path) ?: path.toAbsolutePath()).normalize().toString()
}
/** Height that fits at most [MAX_FILE_ROWS] rows, or 0 when the list is short enough to show in full. */
private fun rowCap(): Int {
val comps = files.components
@@ -207,17 +220,27 @@ class RevertBanner(
init {
applyStyle()
tip(item.file)
}
fun update(item: DiffFileDto, text: String) {
fun update(item: DiffFileDto, text: String, tip: String) {
if (label.text != text) label.text = text
if (label.toolTipText != item.file) label.toolTipText = item.file
if (panel.toolTipText != tip) tip(tip)
badge.update(item.additions, item.deletions)
}
fun applyStyle() {
label.foreground = UIUtil.getLabelForeground()
}
private fun tip(text: String) {
tip(panel, text)
}
private fun tip(node: Component, text: String) {
if (node is JComponent && node.toolTipText != text) node.toolTipText = text
if (node is Container) node.components.forEach { tip(it, text) }
}
}
}
@@ -39,6 +39,8 @@ import ai.kilocode.rpc.dto.MessageTimeDto
import ai.kilocode.rpc.dto.MessageWithPartsDto
import ai.kilocode.rpc.dto.PartDto
import ai.kilocode.rpc.dto.SessionRevertDto
import ai.kilocode.rpc.dto.SessionDto
import ai.kilocode.rpc.dto.SessionTimeDto
import ai.kilocode.rpc.dto.TodoDto
import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI
import com.intellij.openapi.Disposable
@@ -1161,6 +1163,31 @@ class SessionMessageListPanelTest : BasePlatformTestCase() {
assertTrue(labels.contains("Button.kt" to "packages/ui/src/Button.kt"))
}
fun `test rollback banner uses full path tooltip for entire file row`() {
val banner = RevertBanner(model, {}, {}, {})
model.setSession(SessionDto(
id = "ses",
projectID = "proj",
directory = "/workspace/root",
title = "Session",
version = "1",
time = SessionTimeDto(0.0, 0.0),
))
model.upsertMessage(msg("u1", "user"))
model.setRevert(SessionRevertDto("u1", snapshot = "snap1"))
model.setDiff(listOf(
DiffFileDto("project/dir1/shared-alpha.txt", 0, 4),
DiffFileDto("project/dir2/shared-alpha.txt", 0, 4),
))
banner.update()
val label = rowLabels(banner).first { it.text == "dir1/shared-alpha.txt" }
val row = label.parent as JComponent
assertEquals("/workspace/root/project/dir1/shared-alpha.txt", row.toolTipText)
assertTrue(components(row).filterIsInstance<JComponent>().all { it.toolTipText == "/workspace/root/project/dir1/shared-alpha.txt" })
}
fun `test rollback banner opens rolled back diff`() {
val diff = DiffFileDto("src/A.kt", 1, 0, PATCH, "modified")
val opened = mutableListOf<List<DiffFileDto>>()