Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.ExternalAnnotator
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.actionSystem.ActionGroup
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.colors.EditorColors
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDocumentManager
Expand All @@ -28,8 +33,8 @@ import com.usecodex.jetbrains.CodexIcons
import com.usecodex.jetbrains.Debouncer
import com.usecodex.jetbrains.Errors
import com.usecodex.jetbrains.context.ContextStore
import com.usecodex.jetbrains.events.messages.runWithUser
import com.usecodex.jetbrains.editor.util.EditorFilesHandler
import com.usecodex.jetbrains.events.messages.runWithUser
import com.usecodex.jetbrains.git.CodexGitService
import com.usecodex.jetbrains.settings.CodexApplicationSettings
import com.usecodex.jetbrains.toErrorCtx
Expand Down Expand Up @@ -150,7 +155,7 @@ class ContextAnnotator : ExternalAnnotator<SetupInfo, CodexHighlightingData>(),

LOG.debug("${scope.startLine} - ${scope.endLine} for ${scope.file?.name}")

// Substract 1 from the line numbers to get 0-based offsets required by the IDE
// Subtract 1 from the line numbers to get 0-based offsets required by the IDE
val startLine = scope.startLine!! - 1
val endLine = scope.endLine?.let { it - 1 } ?: startLine
context.id to TextRange(
Expand Down Expand Up @@ -182,7 +187,7 @@ class ContextAnnotator : ExternalAnnotator<SetupInfo, CodexHighlightingData>(),
// Only render one gutter icon per start line
if (contextId in contextIdsToRenderGutterIconFor) {
contextIdGutterIconGroupedByOffset[textRange.startOffset]?.let { contextIds ->
gutterIconRenderer(ContextGutterIconRenderer(contextIds))
gutterIconRenderer(ContextGutterIconRenderer(contextIds, highlightingData))
}
}
create()
Expand All @@ -192,13 +197,56 @@ class ContextAnnotator : ExternalAnnotator<SetupInfo, CodexHighlightingData>(),
}
}

class ContextGutterIconRenderer(val contextIds: List<Int>) : GutterIconRenderer() {
class ContextGutterIconRenderer(val contextIds: List<Int>, private val highlightingData: CodexHighlightingData) : GutterIconRenderer() {
override fun equals(other: Any?): Boolean = when (other) {
is ContextGutterIconRenderer -> contextIds == other.contextIds
else -> false
}

// popup menu with actions to allow navigating to multiple codexes
override fun getPopupMenuActions(): ActionGroup? {
return when (contextIds.size) {
0, 1 -> null
else -> contextIds.mapNotNull { contextId ->
// fixme: slow lookup! only for demo purposes
highlightingData.contexts.firstOrNull { it.id == contextId }?.let(::NavigateToCodexAction)
}.toList().takeIf { it.isNotEmpty() }?.let(::DefaultActionGroup)
}
}

// show hand cursor on hover, but only if there's just one context (i.e. the same condition as for getClickAction())
override fun isNavigateAction(): Boolean {
return contextIds.size == 1
}

// navigate on left-click, but only if there's just one context
override fun getClickAction(): AnAction? {
return when (contextIds.size) {
1 -> {
// fixme slow lookup
val codex = highlightingData.contexts.firstOrNull { it.id == contextIds[0] }
codex?.let(::NavigateToCodexAction)
}

else -> null
}
}

override fun getTooltipText(): String? {
return highlightingData.contexts.firstOrNull { it.id == contextIds[0] }?.let {
"Navigate to ${it.scope?.file?.name}"
}
}

override fun isDumbAware(): Boolean = true

override fun hashCode(): Int = this.contextIds.hashCode()

override fun getIcon(): Icon = CodexIcons.GutterIcon
}

class NavigateToCodexAction(val context: Context) : AnAction("Navigate to ${context.codex?.name ?: context.id}") {
override fun actionPerformed(e: AnActionEvent) {
Messages.showInfoMessage("Navigating to $context...", "Codex")
}
}