Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run editor action on save #118

Closed
quilicicf opened this issue Oct 27, 2017 · 74 comments
Closed

Run editor action on save #118

quilicicf opened this issue Oct 27, 2017 · 74 comments
Milestone

Comments

@quilicicf
Copy link

quilicicf commented Oct 27, 2017

Hi,

I was wondering if it could be possible to add an option to run an external tool on the file on save.

My use-case

I've got a markdown that I edit and a script that parses it to generate the ToC.
I'd like to run the script each time I save the file.

@markiewb
Copy link
Contributor

markiewb commented Oct 27, 2017 via email

@quilicicf
Copy link
Author

quilicicf commented Oct 29, 2017

I'm not exactly sure file watchers is what I'm looking for, correct me if I'm wrong but what I gathered from looking at both these plugins was that:

  • File watchers: is to be used when one wants to generate other files from the file that is being edited.
    • Typical use cases:
      • Less files => one CSS file
      • JS files => one bundle file
  • Save actions: is to be used when the file currently being edited should be edited further by a script
    • Typical use cases:
      • Formatting of code
      • Code style updates

When I try to use file watchers, the script execution triggers the file watcher which make a recursive call that crashes IntelliJ.
I was hoping save actions would not get triggered by external modifications like file watchers.

@dubreuia
Copy link
Owner

Hey @quilicicf,

This was already asked for similar purposes see #72, and #61 that was actually implemented by jetbrains. I think what you're asking fits the save-actions plugin: "user modifies file -> save-actions automatically modifies it too -> intellij saves on disk"

The problem is that I'm not going to call a random script on disk, this is a security issue (commit a settings file and a script file in a repo that uses save-actions, bam you have remote execution). I don't even know if that would work, because intellij calling a (bash?) script is probably async, so it would probably save before the script ends.

The only solutions I see for now is to implement your TOC generation directly in save-actions (nope) or call another plugin in intellij (better, but not great).

So I don't really have a solution for you, but I'm not against the idea. Probably @markiewb 's solution is your best way to go for now.

PS hey you work at restlet, say hi to jonathan :)

@quilicicf
Copy link
Author

It looks like I'm gonna keep running the external tool by hand with a shortcut then, it's not that bad.

Thanks for taking the time to get into details!

I'm not sure if I should close this ticket or if you want to keep it open for reference, I'll let you guys see to it?

PS: Jonathan says hi too ;-)

@quilicicf quilicicf reopened this Oct 30, 2017
@dubreuia
Copy link
Owner

I never realized that you could launch an external tool from Intellij... You can probably retrieve the Action with ActionManager.getInstance().getAction("ACTION ID").actionPerformed(event); so the save actions plugin could have a list of custom configurable actions to launch (ids).

I won't have time to implement that anytime soon, but it's definitely possible to do and and you can submit a PR anytime. Check out the https://github.com/dubreuia/intellij-plugin-save-actions#contributing section to get you started.

@quilicicf
Copy link
Author

I'll get a look (not next month) thanks!

@markiewb
Copy link
Contributor

Yes, IDEA supports external tools. I guess there is also API to find and invoke the configured external tools.

The current integration of external tools is as follows
image
image

@blowsie
Copy link

blowsie commented Feb 23, 2018

It would be great to be able to run any webstorm action. This would enable you to use the newly added prettier functionality on save.

@blowsie
Copy link

blowsie commented Mar 12, 2018

Or any other IDE actions Ctrl + Shift + A

@dubreuia dubreuia changed the title Add external tool run Run editor action on save Mar 18, 2018
@dubreuia dubreuia added the NEXT label Sep 19, 2018
@dubreuia
Copy link
Owner

I'm working on this one right now.

@dubreuia
Copy link
Owner

dubreuia commented Jan 18, 2019

If someone want to test the feature, I've created a release candidate 1.4.0-RC1. You can configure the plugin to execute on save a "quick list", which is a series of editor actions (pretty much anything that can be executed with "CTRL + SHIFT + A").

For example I've configured the plugin to execute a quick list that launches my test suite when I save.

Any feedback welcome.

Save Actions-1.4.0-RC1.zip

@dubreuia dubreuia removed the next label Jan 18, 2019
@dubreuia dubreuia added this to the 1.4.0 milestone Jan 18, 2019
@blowsie
Copy link

blowsie commented Jan 18, 2019

I installed the plugin from zip but don't see the options... Am i missing something?

image

@dubreuia
Copy link
Owner

My mistake, I'm fixing.

@dubreuia
Copy link
Owner

Done: Save Actions-1.4.0-RC2.zip

@quilicicf
Copy link
Author

Reminder set to try that on monday, thanks :)

@ngbrown
Copy link

ngbrown commented Jan 19, 2019

I added the 1.4.0 RC2 plugin to WebStorm, and can configure it to select a quick list, but it doesn't actually seem to run it. I tried both normal Ctrl+S, and the menu items for Save Actions.

I've verified the quick list items do something by manually running them.

This is how my quick list is configured:
screenshot - 2019-01-18 5_25_16 pm

I also tried adding other items with obvious effects to the quick list like "Backspace".

This is how Save Actions is configured:
screenshot - 2019-01-18 5_29_24 pm

Any ideas?

@dubreuia
Copy link
Owner

Can you guys help me test this version please? I've re-added editor actions in the settings, it looks good and could be released in the next 1.8.0 if it works ok for you. I've changed the order of the quick lists, so you might have to re-choose your quick list in the save action settings page.

Here is the jar: intellij-plugin-save-actions-1.8.0-RC1.zip

(it will work on 2019.x only, if you need another version I'll change the manifest version)

@ozum
Copy link

ozum commented Dec 12, 2019

It Works
Plugin: 1.8.0-RC1
WebStorm: 2019.3

What
Quick List:

  • "Reformat with Prettier

What Not

I won't have time to implement "Fix ESLint Problems"

Not expecting this to work, but tried anyway:
Quick List

  • "Fix ESLint Problems"

@davecoates
Copy link

Works for me in Pycharm 2019.3 👍

@dubreuia
Copy link
Owner

Ok thank you for testing guys. I'm releasing 1.8.0 this weekend.

I'll close this issue, but please reopen an issue for specific actions that doesn't work (ie @ozum for ESLint).

@efstathiosntonas
Copy link

Confirmed working as a charm in Webstorm 2019.3, using prettier from quick lists

@quilicicf
Copy link
Author

👏 🎉 Thanks all

@dubreuia
Copy link
Owner

Released in 1.8.0.

@dubreuia
Copy link
Owner

@ozum I created #287

@ozum
Copy link

ozum commented Dec 14, 2019

@ozum I created #287

Thanks, I added a summary to that issue for those who don't desire to read this long thread.

@rcollette
Copy link

Since there can be multiple quicklists defined and there is only a checkbox (experimental) to enable this, how does it know what to run?

@rcollette
Copy link

Sorry, in my theme the drop down to select the quick list wasn't very noticeable.

image

@dubreuia
Copy link
Owner

@rcollette Yes, I was about to tell you about the drop down. I can make it show more, I'm using the light theme which makes it more visible.

The code has been written to execute multiple quick lists but I haven't coded the UI to support that (I don't know if its useful or not).

@rcollette
Copy link

I can't think of a use case for multiple lists. Thanks for the UX consideration.

@ozum
Copy link

ozum commented Dec 20, 2019

@dubreuia maybe you can exchange checkbox with an empty field in list. i.e. when it is empty it means no action.

@OlgaLevanova
Copy link

OlgaLevanova commented Jan 7, 2020

Hi there,

I use Build actions feature to fix stylelint errors and it works great. But I got 1 issue. When I open my project in PhpStorm and save my changes I got error:

java.lang.IllegalArgumentException: Argument for @NotNull parameter 'action' of com/intellij/openapi/actionSystem/AnActionEvent.createFromAnAction must not be null
	at com.intellij.openapi.actionSystem.AnActionEvent.$$$reportNull$$$0(AnActionEvent.java)
	at com.intellij.openapi.actionSystem.AnActionEvent.createFromAnAction(AnActionEvent.java)
	at com.dubreuia.processors.BuildProcessor.lambda$static$4(BuildProcessor.java:84)
	at com.dubreuia.processors.SaveReadCommand.execute(SaveReadCommand.java:25)
	at com.dubreuia.core.component.Engine.lambda$processPsiFiles$5(Engine.java:81)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.stream.ReferencePipeline$11$1.accept(ReferencePipeline.java:442)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at com.dubreuia.core.component.Engine.processPsiFiles(Engine.java:82)
	at com.dubreuia.core.component.Engine.processPsiFilesIfNecessary(Engine.java:65)
	at com.dubreuia.core.component.SaveActionManager.guardedProcessPsiFiles(SaveActionManager.java:144)
	at com.dubreuia.core.component.SaveActionManager.lambda$beforeDocumentsSaving$3(SaveActionManager.java:128)
	at java.base/java.util.HashMap.forEach(HashMap.java:1336)
	at com.dubreuia.core.component.SaveActionManager.beforeDocumentsSaving(SaveActionManager.java:127)
	at com.dubreuia.core.component.SaveActionManager.beforeAllDocumentsSaving(SaveActionManager.java:112)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.intellij.util.messages.impl.MessageBusImpl.invokeListener(MessageBusImpl.java:513)
	at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:142)
	at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:438)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpWaitingBuses(MessageBusImpl.java:398)
	at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:388)
	at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:372)
	at com.intellij.util.messages.impl.MessageBusImpl.lambda$createTopicHandler$1(MessageBusImpl.java:241)
	at com.sun.proxy.$Proxy23.beforeAllDocumentsSaving(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.multiCast(FileDocumentManagerImpl.java:162)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.lambda$new$0(FileDocumentManagerImpl.java:125)
	at com.sun.proxy.$Proxy23.beforeAllDocumentsSaving(Unknown Source)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.saveAllDocuments(FileDocumentManagerImpl.java:311)
	at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.saveAllDocuments(FileDocumentManagerImpl.java:301)
	at com.intellij.ide.actions.SaveAllAction.actionPerformed(SaveAllAction.kt:20)
	at com.intellij.openapi.actionSystem.ex.ActionUtil$1.run(ActionUtil.java:298)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:315)
	at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher$1.performAction(IdeKeyEventDispatcher.java:604)
	at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.lambda$processAction$3(IdeKeyEventDispatcher.java:657)
	at com.intellij.openapi.application.TransactionGuardImpl.performUserActivity(TransactionGuardImpl.java:193)
	at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processAction(IdeKeyEventDispatcher.java:656)
	at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processActionOrWaitSecondStroke(IdeKeyEventDispatcher.java:517)
	at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.inInitState(IdeKeyEventDispatcher.java:472)
	at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.dispatchKeyEvent(IdeKeyEventDispatcher.java:221)
	at com.intellij.ide.IdeEventQueue.dispatchKeyEvent(IdeEventQueue.java:830)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:775)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:424)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:698)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:423)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

And code is not fixed. So every time I have to go to Settings -> Tools -> External Tools and re-apply Stylelint tool. After that there is no errors and stylelint works.

Can you please check if it's 'Save Actions' issue? Thanks

OS: Ubuntu 18.04.3
PhpStorm: 2019.3
Save Actions: 1.9.0+2019.3

External tool: Stylelint
Screenshot settings Stylelint

Quick lists: Force refresh -> Stylelint
Save Actions config:
Screenshot settings Save Actions

@dubreuia
Copy link
Owner

dubreuia commented Jan 8, 2020

Thanks @OlgaLevanova, I've created #292

@OlgaLevanova
Copy link

@dubreuia Works perfect. Thanks!

@ozgeneral
Copy link

Would it be possible to pass the file path that is being saved as an input to the script that would be called by the external tools? (or to setup an environment variable with this?)

use case:
to run custom reformattings only on the saved files instead of all modified files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests