How to add an action in the Solution view (Rider)

Hi,
I know how to add an action when doing a right-click in the Project view in IntelliJ:

<action id="..." class="..." text="..." description="...">
    <add-to-group group-id="ProjectViewPopupMenu" anchor="last"/>
</action>

Unfortunately, it does nothing in Rider in the Solution and File System views. Some help would be appreciated.
Thx!

Anyone has an idea? I’m trying to find the group-id of the Solution view and, ideally, of the File System view as well, in Rider.

Upfront, I’m NOT a Rider person, but here are two tips for self-help:

Tip 1

Are you using the internal tools to investigate such things? If not, turn on internal mode, open up Rider and use Tools | Internal Actions | UI Inspector. I didn’t actually need to enable this, it just worked for me when having internal mode turned on.

Now you can Ctrl + Alt + Click on any UI component and get lots of information. So when I go into the Solution view, right-click to open the pop-up, and then press Ctrl+Alt+Click on any action, I can already see lots of info. Sub tip: Hold Alt down and just hover over any element and the UI Inspector will update accordingly.

If you play around with this, you already get some clues. Like on the Edit group, you find that it has a Group SolutionExplorerPopupMenu.Edit.

But why stop there, right?

Tip 2

You do have a Rider installation and things like action groups are usually stored in .xml files. Of course everything is packed in jars, but that doesn’t stop us and you could try a simple guessing game:

You want to know if there is an xml file somewhere that very likely has a filename containing “Rider” and maybe “Actions”. So go into your Rider installation path (you find it in Toolbox | Rider | … | Settings) and open a terminal. We can use find, unzip and grep to check all jars on the fly:

find /path/to/rider -name "*.jar" -exec sh -c 'unzip -l "$1" 2>/dev/null | grep -E ".*Rider.*\.xml$" && echo "=== Found in: $1 ===" ' _ {} \;

And look what you find in lib/modules/intellij.rider.jar:

META-INF/RiderProjectViewActions.xml

You can simply copy and unpack that jar with zip. If you look at the contents, I believe what you were searching for is

<group id="SolutionExplorerPopupMenu">

But even better, now you know how to help yourself.

1 Like

I’m already a heavy user of the UI Inspector. SolutionExplorerPopupMenu.Edit doesn’t work :wink:

I also listed some available groupIds (mostly for actions) at runtime:

Aspire.AddToSolution
Aspire.Solution.Manifest
BuildSolutionAction
BuildSolutionBar
BuildSolutionWithDiagnosticsAction
BuildWholeSolutionAction
CleanSolutionAction
DumpSolutionBuilderAction
DumpSolutionBuilderBuildReasonsAction
EditSolutionFilterAction
FindDependantCodeInSolutionAction
FindInSolutionView
LocateInSolutionView
NewRiderSolutionFolder
OpenSelectedSolution
OpenSolutionApplicationHostConfig
RdJsonSelectSolution
ReSharperGotoNextErrorInSolution
ReSharperGotoPrevErrorInSolution
RebuildSolutionAction
RebuildSolutionWithDiagnosticsAction
Rider.ProblemsView.ErrorsInSolution
Rider.UnitTesting.RunSolution
Rider.UnitTesting.RunSolution.Plugin
Rider.UnitTesting.RunSolutionTw
Rider.UnitTesting.RunSolutionTw.Plugin
RiderAddDockerComposeFileToSolutionAction
RiderAddProjectDependenciesToSolutionFilterAction
RiderAddProjectDependencyTreeToSolutionFilterAction
RiderAddToSolutionFilterProjectAction
RiderAddToSolutionFilterProjectWithDependenciesAction
RiderDotCoverUnitTestCoverSolutionAction
RiderDotCoverUnitTestCoverSolutionTwAction
RiderDumpSolutionBuilder
RiderNewSolution
RiderOpenSolution
RiderRemoveFromSolutionFilterProjectAction
RiderReopenSolutionAction
RiderUnitTestDotMemoryUnitSolutionAction
RiderUnitTestDotMemoryUnitSolutionTwAction
RiderUnitTestProfileSolutionAction
RiderUnitTestProfileSolutionTwAction
RiderUnitTestProjectOrSolutionHelpAction
RiderUnitTestRunSolutionAction
RiderUnitTestRunSolutionTwAction
RiderUnitTestSessionBuildPolicyWholeSolutionAction
SaveAsSolutionFilterAction
ShowAllInSolutionExplorer
ShowArchitectureDiagramFromSolutionExplorerActionGroup
ShowSolutionConfigurationOnToolbarAction
ShowSolutionPropertiesAction
SolutionExplorerEmptyPopupMenu
SolutionExplorerPopupMenu
SolutionExplorerPopupMenu.Database
SolutionExplorerPopupMenu.Diagrams
SolutionExplorerPopupMenu.Edit
SolutionExplorerPopupMenu.NuGet
SolutionExplorerPopupMenu.ProjectManagement
SolutionExplorerPopupMenu.Repl
SolutionExplorerPopupMenu.Tools
SolutionExplorerPopupMenuForImports
SolutionExplorerPopupMenuForReference
SolutionExplorerPopupMenuForReferenceFolder
SolutionExplorerPopupMenuForSourceGenerators
SolutionExplorerPopupMenuForWebReference
SolutionExplorerShowActions
SolutionFilterActions
SolutionSaveAsActions
SolutionViewAddGroup
SolutionViewAddGroup.ContainersSection
SolutionViewAddGroup.PrimarySection
SolutionViewAddGroup.SolutionSection
SolutionViewAddGroup.SpecialSection
SolutionViewAddGroup.TechnologySection
SolutionViewContextMenu
StatusBarWidgets.Toggle.SolutionAnalysisIcon
StatusBarWidgets.Toggle.SolutionAnalysisText
ViewInSolutionExplorer

I tested the groupIds that looked promising, like SolutionExplorerPopupMenu, SolutionViewContextMenu etc, but nothing worked for now. This is why I’m asking for help.
Actually, I’m wondering if 3rd-party plugins are allowed to register actions in this menu? (at the base level). I’m certainly missing something.
I’m saying that because I can add actions in the Riglt-click/Open In sub-menu via the RevealGroup and TouchBarDefault_alt groupIds, but these IDs are available in both Project and Solution views.

Also tried ProjectView.ToolWindow.Appearance.Actions, which looked interesting, but no.

Adding to SolutionExplorerPopupMenu is supposed to work. In fact, just checked and it works for me, for both the solution and the file system views.

class MyAction : AnAction() {

    override fun update(e: AnActionEvent) {
        e.presentation.isEnabledAndVisible = true
    }

    override fun actionPerformed(p0: AnActionEvent) {
        TODO("Not yet implemented")
    }
}
<idea-plugin>
    <actions>
        <action id="me.fornever.avaloniarider.actions.MyAction" class="me.fornever.avaloniarider.actions.MyAction"
                text="MyActionName">
            <add-to-group group-id="SolutionExplorerPopupMenu" anchor="first"/>
        </action>
    </actions>
</idea-plugin>

This is exactly what I did, but I get this error (latest Rider EAP):
group with id "SolutionExplorerPopupMenu" isn't registered so the action won't be added to it. I can still invoke my action via “Find Action”, but not from the Solution or File System views.

The stacktrace:

com.intellij.diagnostic.PluginException: lermitage.intellij.extratoolspack2026a1a4.j (keepIDlermitage.intellij.extra.icons.actions.CreateUserIconFromEditAction): group with id "SolutionExplorerPopupMenu" isn't registered so the action won't be added to it; the action can be invoked via "Find Action" (module=PluginMainDescriptor(name=Extra Tools Pack, id=lermitage.ij.all.pack, version=2026.1.4, isBundled=false, path=~/.local/share/JetBrains/Rider2026.1/Extra Tools Pack)) [Plugin: lermitage.ij.all.pack]
	at com.intellij.openapi.actionSystem.impl.ActionManagerImplKt.reportActionError(ActionManagerImpl.kt:1723)
	at com.intellij.openapi.actionSystem.impl.ActionManagerImplKt.access$reportActionError(ActionManagerImpl.kt:1)
	at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.getParentGroup(ActionManagerImpl.kt:856)
	at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.processAddToGroupNode(ActionManagerImpl.kt:815)
	at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.processActionElement(ActionManagerImpl.kt:556)
	at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.registerPluginActions(ActionManagerImpl.kt:422)
	at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.doRegisterActions(ActionManagerImpl.kt:297)
	at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.<init>(ActionManagerImpl.kt:198)
	at com.jetbrains.rdserver.ui.actionPopupMenu.BackendActionManager.<init>(BackendActionManager.kt:47)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:735)
	at com.intellij.platform.instanceContainer.instantiation.InstantiateKt.instantiate$lambda$0(instantiate.kt:52)
	at com.intellij.platform.instanceContainer.instantiation.InstantiateKt.instantiate$lambda$3$0(instantiate.kt:294)
	at com.intellij.platform.instanceContainer.instantiation.InstantiateKt.withStoredTemporaryContext(instantiate.kt:310)
	at com.intellij.platform.instanceContainer.instantiation.InstantiateKt.instantiate(instantiate.kt:293)
	at com.intellij.platform.instanceContainer.instantiation.InstantiateKt.instantiate(instantiate.kt:45)
	at com.intellij.serviceContainer.ServiceInstanceInitializer.createInstance$suspendImpl(ServiceInstanceInitializer.kt:39)
	at com.intellij.serviceContainer.ServiceInstanceInitializer.createInstance(ServiceInstanceInitializer.kt)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1$1.invokeSuspend(LazyInstanceHolder.kt:181)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1$1.invoke(LazyInstanceHolder.kt)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1$1.invoke(LazyInstanceHolder.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndspatched(Undispatched.kt:67)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:43)
	at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:165)
	at kotlinx.coroutines.BuildersKt.withContext(Unknown Source)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1.invokeSuspend(LazyInstanceHolder.kt:179)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1.invoke(LazyInstanceHolder.kt)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder$initialize$1.invoke(LazyInstanceHolder.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:20)
	at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:360)
	at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:134)
	at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:53)
	at kotlinx.coroutines.BuildersKt.launch(Unknown Source)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.initialize(LazyInstanceHolder.kt:164)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.access$initialize(LazyInstanceHolder.kt:29)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.tryInitialize(LazyInstanceHolder.kt:154)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.getInstance(LazyInstanceHolder.kt:112)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.getInstance$suspendImpl(LazyInstanceHolder.kt:100)
	at com.intellij.platform.instanceContainer.internal.LazyInstanceHolder.getInstance(LazyInstanceHolder.kt)
	at com.intellij.platform.instanceContainer.internal.InstanceContainerImpl.instance(InstanceContainerImpl.kt:83)
	at com.intellij.serviceContainer.ComponentManagerImpl.getServiceAsync(ComponentManagerImpl.kt:749)
	at com.intellij.platform.ide.bootstrap.ApplicationLoader$preloadNonHeadlessServices$2$5.invokeSuspend(ApplicationLoader.kt:613)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:610)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runDefaultDispatcherTask(CoroutineScheduler.kt:1194)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:906)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:775)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:762)

My code. Am I missing something?

    <actions>
        <action id="keepIDlermitage.intellij.extra.icons.actions.CreateUserIconFromEditAction"
                text="Create Icon for This File"
                class="lermitage.intellij.extra.icons.actions.CreateUserIconFromEditAction">
            <add-to-group group-id="SolutionExplorerPopupMenu" anchor="first"/>
        </action>
package lermitage.intellij.extra.icons.actions;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;

public class CreateUserIconFromEditAction extends AnAction {

    @Override
    public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabledAndVisible(true);
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent anActionEvent) {

    }
}

Nota: I also tried without code obfuscation (I was using Proguard), but it changes nothing.

My class

Do you have a Rider dependency in your plugin descriptor?

This is the plugin I’ve been working with: AvaloniaRider/src/rider/main/resources/META-INF/plugin.xml at a9d234287bbe4744b65eb24ff486cee3f397045a · ForNeVeR/AvaloniaRider · GitHub

It works much better with the Rider dependency.
Thank you very much!

1 Like

It is required usually because affects sorting of init for actions and groups from plugins