Skip to content

Commit

Permalink
Add "Goto Script" tab to the "Find Action" window
Browse files Browse the repository at this point in the history
  • Loading branch information
waleedyaseen committed Aug 29, 2024
1 parent 5962f6c commit b6c340f
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Support for varclan and varclansetting.
- Trigger support for shiftop and onclick variants.
- Support for "midi" type.
- Add "Goto Script" tab to the "Find Action" window.

### Changed

Expand Down
22 changes: 22 additions & 0 deletions src/main/kotlin/io/runescript/plugin/ide/icons/RsIconProvider.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.runescript.plugin.ide.icons

import com.intellij.ide.FileIconProvider

Check warning on line 3 in src/main/kotlin/io/runescript/plugin/ide/icons/RsIconProvider.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import com.intellij.ide.IconProvider
import com.intellij.openapi.project.Project

Check warning on line 5 in src/main/kotlin/io/runescript/plugin/ide/icons/RsIconProvider.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import com.intellij.openapi.vfs.VirtualFile

Check warning on line 6 in src/main/kotlin/io/runescript/plugin/ide/icons/RsIconProvider.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import com.intellij.psi.PsiElement
import io.runescript.plugin.ide.RsIcons

Check warning on line 8 in src/main/kotlin/io/runescript/plugin/ide/icons/RsIconProvider.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import io.runescript.plugin.ide.neptune.isNeptuneBuildFile

Check warning on line 9 in src/main/kotlin/io/runescript/plugin/ide/icons/RsIconProvider.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import io.runescript.plugin.lang.psi.RsScript
import io.runescript.plugin.lang.psi.mixin.getIconForTriggerName
import io.runescript.plugin.lang.psi.triggerName
import javax.swing.Icon

class RsIconProvider : IconProvider() {
override fun getIcon(element: PsiElement, flags: Int): Icon? {
if (element is RsScript) {
return getIconForTriggerName(element.triggerName)
}
return null
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package io.runescript.plugin.ide
package io.runescript.plugin.ide.searchEverywhere

import com.intellij.navigation.ChooseByNameContributorEx
import com.intellij.navigation.GotoClassContributor
import com.intellij.navigation.NavigationItem
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StubIndex
import com.intellij.util.Processor
import com.intellij.util.indexing.FindSymbolParameters
import com.intellij.util.indexing.IdFilter
import io.runescript.plugin.lang.RuneScript
import io.runescript.plugin.lang.psi.RsScript
import io.runescript.plugin.lang.psi.qualifiedName
import io.runescript.plugin.lang.stubs.index.RsClientScriptIndex
import io.runescript.plugin.lang.stubs.index.RsCommandScriptIndex
import io.runescript.plugin.lang.stubs.index.RsProcScriptIndex

class RsGotoClassContributor : ChooseByNameContributorEx, GotoClassContributor {
class RsChooseByNameContributor : ChooseByNameContributorEx {

private val keys = arrayOf(
RsProcScriptIndex.KEY,
Expand Down Expand Up @@ -53,24 +50,4 @@ class RsGotoClassContributor : ChooseByNameContributorEx, GotoClassContributor {
}
}
}

override fun getQualifiedName(item: NavigationItem): String? {
return (item as? RsScript)?.qualifiedName
}

override fun getQualifiedNameSeparator(): String {
return "|"
}

// These are only effective if we override the IdeLanguageCustomization

override fun getElementKind(): String {
return RsBundle.message("go.to.script.kind.text")
}

override fun getElementKindsPluralized(): List<String> {
return listOf(RsBundle.message("go.to.script.kind.text.pluralized"))
}

override fun getElementLanguage() = RuneScript
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.runescript.plugin.ide.searchEverywhere

import com.intellij.ide.IdeBundle
import com.intellij.ide.util.gotoByName.FilteringGotoByModel
import com.intellij.navigation.ChooseByNameContributor
import com.intellij.navigation.NavigationItem
import com.intellij.openapi.project.Project
import com.intellij.ui.IdeUICustomization
import io.runescript.plugin.lang.psi.RsScript
import io.runescript.plugin.lang.psi.qualifiedName

class RsGotoScriptModel(project: Project) :
FilteringGotoByModel<RsTriggerRef>(project, emptyArray()) {

private val contributor = RsChooseByNameContributor()
private val separators = emptyArray<String>()

override fun getPromptText(): String {
return "Enter script name"
}

override fun getNotInMessage(): String {
return IdeUICustomization.getInstance().projectMessage("label.no.matches.found.in.project")

Check failure on line 23 in src/main/kotlin/io/runescript/plugin/ide/searchEverywhere/RsGotoScriptModel.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Invalid property key

Property 'label.no.matches.found.in.project' expected 1 parameter, passed 0
}

override fun getNotFoundMessage(): String {
return IdeBundle.message("label.no.matches.found");

Check warning on line 27 in src/main/kotlin/io/runescript/plugin/ide/searchEverywhere/RsGotoScriptModel.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Redundant semicolon

Redundant semicolon
}

override fun getCheckBoxName(): String? {
return null
}

override fun loadInitialCheckBoxState(): Boolean {
return false
}

override fun saveInitialCheckBoxState(state: Boolean) {
}

override fun getSeparators(): Array<String> {
return separators
}

override fun getFullName(item: Any): String? {
return (item as? RsScript)?.qualifiedName
}

override fun willOpenEditor(): Boolean {
return true
}

override fun filterValueFor(item: NavigationItem): RsTriggerRef? {
return RsTriggerRef.forNavigationItem(item)
}

override fun getContributorList(): MutableList<ChooseByNameContributor> {
return mutableListOf(contributor)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.runescript.plugin.ide.searchEverywhere

import com.intellij.ide.util.gotoByName.ChooseByNameFilterConfiguration
import com.intellij.openapi.components.*
import com.intellij.openapi.project.Project

@Service(Service.Level.PROJECT)
@State(name = "GotoScriptSymbolConfiguration", storages = [Storage(StoragePathMacros.WORKSPACE_FILE)])
class RsGotoScriptSymbolConfiguration : ChooseByNameFilterConfiguration<RsTriggerRef>() {

companion object {
@JvmStatic
fun getInstance(project: Project): RsGotoScriptSymbolConfiguration = project.service()
}

override fun nameForElement(type: RsTriggerRef): String {
return type.displayName
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package io.runescript.plugin.ide.searchEverywhere

import com.intellij.ide.actions.searcheverywhere.*
import com.intellij.ide.actions.searcheverywhere.footer.createPsiExtendedInfo
import com.intellij.ide.util.gotoByName.FilteringGotoByModel
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.Project

class RsSearchEverywhereContributor(event: AnActionEvent) : AbstractGotoSEContributor(event),
SearchFieldActionsContributor {

private val filter = createTriggerFilter(event.getRequiredData(CommonDataKeys.PROJECT))

override fun getGroupName(): String {
return "Scripts"
}

override fun getFullGroupName(): String {
return "Scripts"
}

override fun getSortWeight(): Int {
return 400
}

override fun createModel(project: Project): FilteringGotoByModel<RsTriggerRef> {
val model = RsGotoScriptModel(project)
model.setFilterItems(filter.selectedElements)
return model
}

override fun getActions(onChanged: Runnable): List<AnAction> {
return doGetActions(filter, RsTriggerFilterCollector(), onChanged)
}

override fun isEmptyPatternSupported(): Boolean {
return true
}

@Suppress("OVERRIDE_DEPRECATION")
override fun getElementPriority(element: Any, searchPattern: String): Int {
return super.getElementPriority(element, searchPattern) + 5
}

override fun createExtendedInfo(): ExtendedInfo {
return createPsiExtendedInfo()
}

class Factory : SearchEverywhereContributorFactory<Any> {
override fun createContributor(initEvent: AnActionEvent): SearchEverywhereContributor<Any> {
return PSIPresentationBgRendererWrapper.wrapIfNecessary(RsSearchEverywhereContributor(initEvent))
}

override fun isAvailable(project: Project): Boolean {
return true
}
}

companion object {
fun createTriggerFilter(project: Project): PersistentSearchEverywhereContributorFilter<RsTriggerRef> {
val items = RsTriggerRef.forAllTriggers()
val persistentConfig = RsGotoScriptSymbolConfiguration.getInstance(project)
return PersistentSearchEverywhereContributorFilter(
items,
persistentConfig,
RsTriggerRef::displayName,
RsTriggerRef::icon
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.runescript.plugin.ide.searchEverywhere;

import com.intellij.ide.actions.searcheverywhere.SearchEverywhereFiltersStatisticsCollector;

public class RsTriggerFilterCollector extends SearchEverywhereFiltersStatisticsCollector.BaseFilterStatisticsCollector<RsTriggerRef> {

@Override
public void elementMarkChanged(RsTriggerRef element, boolean isMarked) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.runescript.plugin.ide.searchEverywhere

import com.intellij.navigation.NavigationItem
import com.intellij.openapi.util.text.StringUtil
import io.runescript.plugin.ide.RsIcons
import io.runescript.plugin.lang.psi.RsScript
import io.runescript.plugin.lang.psi.triggerName
import io.runescript.plugin.lang.psi.type.trigger.RsTriggerType
import javax.swing.Icon

data class RsTriggerRef(val displayName: String, val icon: Icon?) {

companion object {
@JvmStatic
fun forTrigger(trigger: RsTriggerType): RsTriggerRef = RsTriggerRef(
trigger.literal,
when (trigger) {
RsTriggerType.PROC -> RsIcons.GutterProc
RsTriggerType.CLIENTSCRIPT -> RsIcons.GutterClientScript
RsTriggerType.COMMAND -> RsIcons.GutterCommand
else -> RsIcons.GutterOther
}
)

@JvmStatic
fun forNavigationItem(item: NavigationItem): RsTriggerRef? {
val trigger = RsTriggerType.lookup((item as RsScript).triggerName) ?: return null
return forTrigger(trigger)
}

@JvmStatic
fun forAllTriggers(): List<RsTriggerRef> {
return RsTriggerType.values()
.sortedWith { a, b -> StringUtil.naturalCompare(a.literal, b.literal) }
.map { forTrigger(it) }
}
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as RsTriggerRef

return displayName == other.displayName
}

override fun hashCode(): Int {
return displayName.hashCode()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import io.runescript.plugin.ide.codeInsight.controlFlow.RsControlFlowBuilder
import io.runescript.plugin.ide.highlight.RsSyntaxHighlighterColors
import io.runescript.plugin.lang.psi.*
import io.runescript.plugin.lang.stubs.RsScriptStub
import javax.swing.Icon

abstract class RsScriptMixin : StubBasedPsiElementBase<RsScriptStub>, RsScript {

Expand All @@ -36,7 +37,12 @@ abstract class RsScriptMixin : StubBasedPsiElementBase<RsScriptStub>, RsScript {
CachedValueProvider.Result(controlFlow, this)
}

override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean {
override fun processDeclarations(
processor: PsiScopeProcessor,
state: ResolveState,
lastParent: PsiElement?,
place: PsiElement
): Boolean {
parameterList?.let {
if (!it.processDeclarations(processor, state, lastParent, place)) {
return false
Expand All @@ -46,12 +52,7 @@ abstract class RsScriptMixin : StubBasedPsiElementBase<RsScriptStub>, RsScript {
}

override fun getPresentation(): ItemPresentation? {
val icon = when (triggerName) {
"proc" -> RsIcons.GutterProc
"clientscript" -> RsIcons.GutterClientScript
"command" -> RsIcons.GutterCommand
else -> RsIcons.GutterOther
}
val icon = getIconForTriggerName(triggerName)
return PresentationData(qualifiedName, containingFile.name, icon, RsSyntaxHighlighterColors.SCRIPT_DECLARATION)
}

Expand All @@ -75,4 +76,13 @@ abstract class RsScriptMixin : StubBasedPsiElementBase<RsScriptStub>, RsScript {
override fun getTextOffset(): Int {
return scriptNameExpression.startOffset
}
}

fun getIconForTriggerName(triggerName: String): Icon {
return when (triggerName) {
"proc" -> RsIcons.GutterProc
"clientscript" -> RsIcons.GutterClientScript
"command" -> RsIcons.GutterCommand
else -> RsIcons.GutterOther
}
}
3 changes: 2 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
implementationClass="io.runescript.plugin.ide.filetypes.RsFileType" fieldName="INSTANCE"
extensions="cs2"/>
<fileIconProvider order="first" implementation="io.runescript.plugin.ide.icons.NeptuneIconProvider" />
<iconProvider implementation="io.runescript.plugin.ide.icons.RsIconProvider" />

<!-- Project & Modules -->
<moduleBuilder builderClass="io.runescript.plugin.ide.projectWizard.NeptuneModuleBuilder"/>
Expand Down Expand Up @@ -42,7 +43,7 @@
<stubIndex implementation="io.runescript.plugin.lang.stubs.index.RsClientScriptIndex"/>
<stubIndex implementation="io.runescript.plugin.lang.stubs.index.RsCommandScriptIndex"/>
<stubIndex implementation="io.runescript.plugin.lang.stubs.index.RsScriptIndex"/>
<gotoClassContributor implementation="io.runescript.plugin.ide.RsGotoClassContributor"/>
<searchEverywhereContributor implementation="io.runescript.plugin.ide.searchEverywhere.RsSearchEverywhereContributor$Factory"/>
<lang.elementManipulator forClass="io.runescript.plugin.lang.psi.RsGosubExpression" implementationClass="io.runescript.plugin.lang.psi.manipulator.RsGosubExpressionManipulator"/>
<lang.elementManipulator forClass="io.runescript.plugin.lang.psi.RsStringLiteralContent" implementationClass="io.runescript.plugin.lang.psi.manipulator.RsStringLiteralContentManipulator"/>
<lang.elementManipulator forClass="io.runescript.plugin.lang.doc.psi.impl.RsDocName" implementationClass="io.runescript.plugin.lang.psi.manipulator.RsDocNameManipulator"/>
Expand Down

0 comments on commit b6c340f

Please sign in to comment.