diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/diff/DiffAcceptedPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/diff/DiffAcceptedPanel.kt index b12e2a34..72adcc91 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/diff/DiffAcceptedPanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/diff/DiffAcceptedPanel.kt @@ -53,7 +53,7 @@ class DiffAcceptedPanel( LocalFileSystem.getInstance().findFileByPath(filePath)?.let { vFile -> FileEditorManager.getInstance(project).openFile(vFile, true) } - } + }.apply { toolTipText = filePath } private fun createLeftPanel(fileLink: ActionLink, statsPanel: JPanel): JPanel = JPanel().apply { @@ -115,4 +115,4 @@ class DiffAcceptedPanel( add(viewDetailsLink) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt index b1077f11..3ab43ead 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt @@ -138,6 +138,7 @@ abstract class HeaderPanel(protected val config: HeaderConfig) : BorderLayoutPan OpenFileAction.openFile(virtualFile, config.project) }.apply { setExternalLinkIcon() + toolTipText = virtualFile.path }) add(statsComponent) } @@ -176,7 +177,10 @@ abstract class HeaderPanel(protected val config: HeaderConfig) : BorderLayoutPan ProjectView.getInstance(config.project).select(null, newFile, true) } } - }.apply { icon = AllIcons.General.InlineAdd } + }.apply { + icon = AllIcons.General.InlineAdd + toolTipText = filePath + } return actionLink } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/UserMessagePanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/UserMessagePanel.kt index 78f760fa..5bfee8a0 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/UserMessagePanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/ui/UserMessagePanel.kt @@ -214,6 +214,7 @@ class UserMessagePanel( }) actionLink.icon = if (it.isDirectory) AllIcons.Nodes.Folder else it.fileType.icon + actionLink.toolTipText = it.path actionLink } .toList() @@ -258,4 +259,4 @@ class UserMessagePanel( }) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/UserInputHeaderPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/UserInputHeaderPanel.kt index 651abcf4..ec106c7e 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/UserInputHeaderPanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/UserInputHeaderPanel.kt @@ -140,9 +140,9 @@ class UserInputHeaderPanel( private fun createTagPanel(tagDetails: TagDetails) = (if (tagDetails is EditorSelectionTagDetails) { - SelectionTagPanel(tagDetails, tagManager, promptTextField) + SelectionTagPanel(tagDetails, tagManager, promptTextField, project) } else { - object : TagPanel(tagDetails, tagManager, false) { + object : TagPanel(tagDetails, tagManager, false, project) { init { cursor = if (tagDetails is FileTagDetails) diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagDetails.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagDetails.kt index 9375c286..d5df1ea3 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagDetails.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagDetails.kt @@ -20,6 +20,8 @@ sealed class TagDetails( var selected: Boolean = true + abstract fun getTooltipText(): String? + override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is TagDetails) return false @@ -36,6 +38,8 @@ class EditorTagDetails(val virtualFile: VirtualFile, isRemovable: Boolean = true private val type: String = "EditorTagDetails" + override fun getTooltipText(): String = virtualFile.path + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -58,6 +62,8 @@ class FileTagDetails(val virtualFile: VirtualFile) : private val type: String = "FileTagDetails" + override fun getTooltipText(): String = virtualFile.path + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -83,6 +89,8 @@ data class SelectionTagDetails( ) { var selectedText: String? = selectionModel.selectedText private set + + override fun getTooltipText(): String = virtualFile.path } class EditorSelectionTagDetails( @@ -99,6 +107,8 @@ class EditorSelectionTagDetails( var selectedText: String? = selectionModel.selectedText private set + override fun getTooltipText(): String = virtualFile.path + override fun equals(other: Any?): Boolean { if (other === null) return false return other::class == this::class @@ -110,33 +120,55 @@ class EditorSelectionTagDetails( } data class DocumentationTagDetails(var documentationDetails: DocumentationDetails) : - TagDetails(documentationDetails.name, AllIcons.Toolwindows.Documentation) + TagDetails(documentationDetails.name, AllIcons.Toolwindows.Documentation) { + override fun getTooltipText(): String? = documentationDetails.url +} data class PersonaTagDetails(var personaDetails: PersonaDetails) : - TagDetails(personaDetails.name, AllIcons.General.User) + TagDetails(personaDetails.name, AllIcons.General.User) { + override fun getTooltipText(): String? = null +} data class GitCommitTagDetails(var gitCommit: GitCommit) : - TagDetails(gitCommit.id.asString().take(6), AllIcons.Vcs.CommitNode) + TagDetails(gitCommit.id.asString().take(6), AllIcons.Vcs.CommitNode) { + override fun getTooltipText(): String? = gitCommit.fullMessage +} class CurrentGitChangesTagDetails : - TagDetails("Current Git Changes", AllIcons.Vcs.CommitNode) + TagDetails("Current Git Changes", AllIcons.Vcs.CommitNode) { + override fun getTooltipText(): String? = null +} data class FolderTagDetails(var folder: VirtualFile) : - TagDetails(folder.name, AllIcons.Nodes.Folder) + TagDetails(folder.name, AllIcons.Nodes.Folder) { + override fun getTooltipText(): String = folder.path +} -class WebTagDetails : TagDetails("Web", AllIcons.General.Web) +class WebTagDetails : TagDetails("Web", AllIcons.General.Web) { + override fun getTooltipText(): String? = null +} data class ImageTagDetails(val imagePath: String) : - TagDetails(imagePath.substringAfterLast('/'), AllIcons.FileTypes.Image) + TagDetails(imagePath.substringAfterLast('/'), AllIcons.FileTypes.Image) { + override fun getTooltipText(): String = imagePath +} data class HistoryTagDetails( val conversationId: UUID, val title: String, -) : TagDetails(title, AllIcons.General.Balloon) +) : TagDetails(title, AllIcons.General.Balloon) { + override fun getTooltipText(): String? = null +} -class EmptyTagDetails : TagDetails("") +class EmptyTagDetails : TagDetails("") { + override fun getTooltipText(): String? = null +} -class CodeAnalyzeTagDetails : TagDetails("Code Analyze", AllIcons.Actions.DependencyAnalyzer) +class CodeAnalyzeTagDetails : TagDetails("Code Analyze", AllIcons.Actions.DependencyAnalyzer) { + override fun getTooltipText(): String? = null +} data class DiagnosticsTagDetails(val virtualFile: VirtualFile) : - TagDetails("${virtualFile.name} Problems", AllIcons.General.InspectionsEye) + TagDetails("${virtualFile.name} Problems", AllIcons.General.InspectionsEye) { + override fun getTooltipText(): String = virtualFile.path +} diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagPanel.kt index b0747714..541d0b2c 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagPanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagPanel.kt @@ -4,6 +4,7 @@ import com.intellij.icons.AllIcons import com.intellij.icons.AllIcons.Actions.Close import com.intellij.openapi.components.service import com.intellij.openapi.editor.colors.EditorColorsManager +import com.intellij.openapi.project.Project import com.intellij.ui.components.JBLabel import com.intellij.util.IconUtil import com.intellij.util.ui.JBUI @@ -23,8 +24,8 @@ abstract class TagPanel( var tagDetails: TagDetails, private val tagManager: TagManager, private val shouldPreventDeselection: Boolean = true, + protected val project: Project, ) : JToggleButton() { - private val label = TagLabel(tagDetails.name, tagDetails.icon, tagDetails.selected) private val closeButton = CloseButton { isVisible = isSelected && tagDetails.isRemovable @@ -43,6 +44,11 @@ abstract class TagPanel( fun update(text: String, icon: Icon? = null) { closeButton.isVisible = isSelected && tagDetails.isRemovable label.update(text, icon, isSelected) + tagDetails.getTooltipText()?.let { tooltip -> + val relativeTooltipText = toProjectRelative(tooltip) + this.toolTipText = relativeTooltipText + label.toolTipText = relativeTooltipText + } revalidate() repaint() } @@ -67,6 +73,11 @@ abstract class TagPanel( cursor = Cursor(Cursor.HAND_CURSOR) isSelected = tagDetails.selected closeButton.isVisible = isSelected && tagDetails.isRemovable + tagDetails.getTooltipText()?.let { tooltip -> + val relativeTooltipText = toProjectRelative(tooltip) + this.toolTipText = relativeTooltipText + label.toolTipText = relativeTooltipText + } val gbc = GridBagConstraints().apply { gridx = 0 @@ -100,6 +111,14 @@ abstract class TagPanel( repaint() } + private fun toProjectRelative(path: String): String? { + val base = project.basePath ?: return path + val baseTrim = base.trimEnd('/', '\\') + return if (path.startsWith("$baseTrim/") || path.startsWith("$baseTrim\\")) { + path.substring(baseTrim.length + 1) + } else path + } + private class TagLabel( name: String, icon: Icon? = null, @@ -158,7 +177,8 @@ class SelectionTagPanel( tagDetails: EditorSelectionTagDetails, tagManager: TagManager, private val promptTextField: PromptTextField, -) : TagPanel(tagDetails, tagManager, true) { + project: Project, +) : TagPanel(tagDetails, tagManager, true, project) { init { cursor = Cursor(Cursor.DEFAULT_CURSOR) @@ -175,4 +195,4 @@ class SelectionTagPanel( override fun onClose() { (tagDetails as? EditorSelectionTagDetails)?.selectionModel?.removeSelection() } -} \ No newline at end of file +}