Intellij plugin development, how to prevent an action from occuring, like closing a tab

Is this possible?

I need to subscribe to the event somehow of closing a tab and possibly return false or similar, i am guessing. I have no idea how though.

This to prevent the closing of a tab. 

What event is that? Where do I register it? And how do I prevent it to bubble to the one that closes it. 

 

I've tried: 

 

listener = new AWTEventListener() {

            @Override
            public void eventDispatched(AWTEvent event) {

                if ( event instanceof KeyEvent ) {
                    KeyEvent kv = (KeyEvent) event;
                    Component component = kv.getComponent();

                    if ( component instanceof EditorComponentImpl) {
                        EditorComponentImpl cp = (EditorComponentImpl) component;

                    }

                    System.out.println("3333333" + component.getClass());
                }

                System.out.println("aaaaaaa" + event.getClass());

            }
        };
0
18 comments

AnAction can be triggered by different means (selected from menu, triggered by keyboard or mouse shortcut, selected from quicklist, selected in Find Action, executed by other action, executed by some listener, etc).

You might try do do smth with AnActionListener.beforeActionPerformed or FileEditorManagerListener.beforeFileClosed, but this is probably a really bad idea.

What are you trying to achieve? 

0
Avatar
Permanently deleted user

Hi Aleksey, 

I am trying to change the behaviour of pin tab, alternativly add a functionality of my own that prevents closing of "pinned" tabs. 

So when a user closes a pinned tab, it should prevent that. The reason is that I always have certain things to the right, but with intellij i can never keep them open. 

Pinned tab is stupid, because it only have an effect when you close all but pinned. 

0
Avatar
Permanently deleted user

Personally, I would just be interested in the keyboard closing CTRL + W ( my settings ) and prevent that if pinned. 

0

You should be able to register new action, similar to EditorTabbedContainer.CloseTab (with an additional `window.isFilePinned(file)` check). You'll also need to register ActionPromoter that would prioritize your action.

<action id="Plugin.Test" class="plugin.MyAction" use-shortcut-of="CloseContent"/>
<actionPromoter implementation="plugin.MyPromoter"/>

public class MyAction extends AnAction implements DumbAware {
public MyAction() {
ActionUtil.copyFrom(this, IdeActions.ACTION_CLOSE);
}

@Override
public void update(final AnActionEvent e) {
e.getPresentation().setEnabled(e.getProject() != null && e.getData(CommonDataKeys.VIRTUAL_FILE) != null);
}

@Override
public void actionPerformed(final AnActionEvent e) {
final FileEditorManagerEx mgr = FileEditorManagerEx.getInstanceEx(e.getProject());
VirtualFile file = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE);
EditorWindow window = mgr.getCurrentWindow();

if (window == null || window.isFilePinned(file)) return;

if (window.findFileComposite(file) != null) {
mgr.closeFile(file, window);
}
}
}

public class MyPromoter implements ActionPromoter {
@Override
public List<AnAction> promote(List<AnAction> actions, DataContext context) {
AnAction action = ContainerUtil.findInstance(actions, MyAction.class);
return action != null ? Collections.singletonList(action) : Collections.emptyList();
}
}
0
Avatar
Permanently deleted user

Thanks Aleksey,

 

I couldn't find any reference to any action promoter in the documentation: 

http://www.jetbrains.org/intellij/sdk/docs/

So I am unsure where to place it in plugin.xml

Some online resource seems to suggest another syntax from yours, but I am unsure.

 

<extensionPoint name="actionPromoter" interface="com.intellij.openapi.actionSystem.ActionPromoter"/>

It refers to an interface here though? 

 

Other than that, I think I've got it.

 

 

0
Avatar
Permanently deleted user

And yes, the method: 

ActionUtil.copyFrom(this, IdeActions.ACTION_CLOSE);

Could not be resolved. The copyFrom method on ActionUtil does not exist in my SDK it seems. 

What version are you on? I am on latest. 16.1.4 or something. 

 

 

 

0
Avatar
Permanently deleted user

Thats actually quite wierd, i found it in the IDEA community github, it should be there, but no in plugin sdk it seems. 

0
Avatar
Permanently deleted user

Where I pointed to the intellij installation. Maybe I should point my sdk to the community version.

0
Avatar
Permanently deleted user

No, that did not work. It has to be an installation path it seems. 

https://www.jetbrains.com/help/idea/2016.1/configuring-intellij-platform-plugin-sdk.html

0
Avatar
Permanently deleted user

I think I managed to do: 

 

MyAction() {

super.copyFrom( ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE) );

}

0
Avatar
Permanently deleted user

And I think I figured out where to place the action promoter. 

 

<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
<actionPromoter implementation="path.to.myactionpromoter"/>
</extensions>

 

0
Avatar
Permanently deleted user

Now it is working great! 

Fantastic, I will publish it in a couple of days :) 

0
Avatar
Permanently deleted user

@Aleksey

These actions work for keyboard closing, but when you close from the menus it does not fire. Do you know what those menu actions to copy are?

 

IdeActions.***CLOSE only lists a couple but i have created actions for all of them, but can't infer the menu close down of tabs. 
0

Hi,

I've used 2016.2 EAP for SDK, glad that you've found a way to do it on stable version.

"Close" from a menu is handled by com.intellij.ide.actions.CloseAction with an EditorTabbedContainer passed as CloseTarget. It is a global action (registered in ActionManager), so you should be able to override it in plugin.

<action id="CloseContent" class="plugin.CloseContent" overrides="true"/>
0
Avatar
Permanently deleted user

 

@Aleksey

Hmm, so actionpromoter not needed here? Override option is enough it seems, but I couldn't do the same on keyboard actions? 

Also, how did you find the id CloseContent? Is there a file I can look at. I am binding CloseAll and so on as well. 

You've been great :)

0

You can't use "overrides" for this keyboard action, because it is created directly (not via ActionManager) and registered on component with AnAction.registerCustomShortcutSet.

I used "Tools -> Internal Actions -> UI Debugger" (you need to enable internal mode to see it)

0
Avatar
Permanently deleted user

I couldn't get any relevant info from the PSI. I am looking at the source code now and can search it. 

Trying to figure out what this action overrides 

com.intellij.ide.actions.CloseAction

Is it the id? O do i need a promoter here too? 

 

I am also getting an error for attribute overrides=true ... I placed <action> in <actions>. It says attribute is not allowed here. 

 

0

If you want to know details - you might check implementation of ActionManagerImpl.

The idea is that ActionManager allows to get AnAction instance by its `id`. These `id` are registered in `.xml` files in `<actions>` block. If two plugins (or a plugin and platform) are trying to assign same `id` - it causes an error. Unless one of them passes `overrides` parameter.

Ex: https://github.com/JetBrains/intellij-community/blob/master/python/src/META-INF/python-core-common.xml#L693

 

>I am also getting an error for attribute

Can you share your plugin.xml somewhere?

0

Please sign in to leave a comment.