Created
January 31, 2024 22:55
-
-
Save micoli/8a2d775fa18067dd76402e57ff240e3b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Need the existence of a .dx-companion.json file at the project root | |
| * | |
| * .dx-companion.json format: | |
| * { | |
| * "actions": [{ | |
| * "label": "action label", | |
| * "command": "sleep 3;exit" | |
| * }], | |
| * "observedFiles": [{ | |
| * "label": "button label", | |
| * "filePath": "src/JavaMagazineJavaFxOnRaspberryPi/src/main/java/module-info2.env", | |
| * "variableName": "BB" | |
| * }] | |
| * } | |
| * | |
| * | |
| * Documentation: | |
| * https://jetbrains.design/intellij/resources/icons_list/ | |
| * https://dmitrykandalov.com/liveplugin | |
| * https://www.javaadvent.com/2021/12/liveplugin.html | |
| */ | |
| // KEEP NEXT LINE | |
| // depends-on-plugin org.jetbrains.plugins.terminal | |
| import org.jetbrains.plugins.terminal.TerminalView | |
| import java.util.regex.Pattern | |
| import javax.swing.Icon; | |
| import javax.swing.* | |
| import groovy.json.JsonSlurper; | |
| import com.intellij.util.Alarm | |
| import com.intellij.openapi.actionSystem.* | |
| import com.intellij.openapi.extensions.Extensions | |
| import com.intellij.openapi.util.IconLoader; | |
| import com.intellij.openapi.project.Project; | |
| import com.intellij.openapi.vfs.*; | |
| import liveplugin.PluginUtil; | |
| import static liveplugin.PluginUtil.show; | |
| import static liveplugin.PluginUtil.* | |
| import static liveplugin.implementation.Misc.scheduleTask | |
| import static liveplugin.PluginUtil.registerToolWindow | |
| class Configuration { | |
| ObservedFile[] observedFiles | |
| ShellAction[] actions | |
| } | |
| class ObservedFile { | |
| String label | |
| String filePath | |
| String variableName | |
| String activeIcon = "actions/inlayRenameInComments.svg" | |
| String inactiveIcon = "actions/inlayRenameInCommentsActive.svg" | |
| String unknownIcon = "expui/fileTypes/unknown.svg" | |
| } | |
| class ShellAction { | |
| String label = 'ShellAction' | |
| String command | |
| String cwd | |
| String icon = "debugger/threadRunning.svg" | |
| } | |
| static Configuration getConfiguration(project) { | |
| VirtualFile projectBaseDir = project.getBaseDir() | |
| VirtualFile configFile = projectBaseDir.findChild('.dx-companion.json') | |
| if (configFile === null) { | |
| show("DXCompanion, no .dx-companion.json found") | |
| return | |
| } | |
| JsonSlurper jsonSlurper = new JsonSlurper() | |
| return jsonSlurper.parseText(new String(configFile.contentsToByteArray())) | |
| } | |
| static JPanel initPlugin(project, Configuration configuration) { | |
| if (configuration === null) { | |
| return; | |
| } | |
| JPanel panel = new JPanel() | |
| List<FileObserverToggle> actions = new ArrayList<>(); | |
| for (def observedFile : configuration.observedFiles) { | |
| panel.add(new FileObserverToggle(observedFile)) | |
| } | |
| if (configuration.actions.length > 0) { | |
| for (def action : configuration.actions) { | |
| panel.add(new ActionButton(project, action)) | |
| } | |
| } | |
| scheduleTask(new Alarm(Alarm.ThreadToUse.SWING_THREAD), 2000) { | |
| for (def component : panel.getComponents()) { | |
| if (component instanceof FileObserverToggle) { | |
| component.check() | |
| } | |
| } | |
| } | |
| panel.revalidate() | |
| return panel | |
| } | |
| class FileObserverToggle extends JButton { | |
| ObservedFile observedFile | |
| Pattern activeRegularExpression; | |
| Pattern disabledRegularExpression; | |
| private enum Status { | |
| Active, Inactive, Unknown; | |
| } | |
| FileObserverToggle(ObservedFile _observedFile) { | |
| super(_observedFile.label); | |
| observedFile = _observedFile | |
| activeRegularExpression = Pattern.compile("^" + observedFile.variableName + "="); | |
| disabledRegularExpression = Pattern.compile("^#" + observedFile.variableName + "="); | |
| addActionListener({ toggle() } as AbstractAction) | |
| } | |
| public void check() { | |
| switch (getStatus()) { | |
| case Status.Active: | |
| setText(observedFile.label) | |
| setIcon(IconLoader.getIcon(observedFile.activeIcon)); | |
| break | |
| case Status.Inactive: | |
| setText("# " + observedFile.label) | |
| setIcon(IconLoader.getIcon(observedFile.inactiveIcon)); | |
| break | |
| case Status.Unknown: | |
| setText(observedFile.label + " not present") | |
| setIcon(IconLoader.getIcon(observedFile.unknownIcon)); | |
| break | |
| } | |
| updateUI() | |
| } | |
| void toggle() { | |
| switch (getStatus()) { | |
| case Status.Active: | |
| replaceInFile(false) | |
| break | |
| case Status.Inactive: | |
| replaceInFile(true) | |
| break | |
| } | |
| check() | |
| } | |
| private Status getStatus() { | |
| File file = new File(observedFile.filePath) | |
| def line = 0; | |
| def result = Status.Unknown; | |
| file.withReader { reader -> | |
| while ((line = reader.readLine()) != null) { | |
| if ((line =~ activeRegularExpression).size() > 0) { | |
| result = Status.Active; | |
| } | |
| if ((line =~ disabledRegularExpression).size() > 0) { | |
| result = Status.Inactive; | |
| } | |
| } | |
| } | |
| return result; | |
| } | |
| private void replaceInFile(boolean toActive) { | |
| def file = new File(observedFile.filePath) | |
| def result = ""; | |
| def line = 0; | |
| file.withReader { reader -> | |
| while ((line = reader.readLine()) != null) { | |
| if (toActive) { | |
| result = result + line.replaceFirst(disabledRegularExpression, "" + observedFile.variableName + "=") + System.getProperty("line.separator") | |
| } else { | |
| result = result + line.replaceFirst(activeRegularExpression, "#" + observedFile.variableName + "=") + System.getProperty("line.separator") | |
| } | |
| } | |
| } | |
| file.text = result | |
| liveplugin.PluginUtil.show(observedFile.variableName + " " + (toActive ? "activated" : "deactivated")) | |
| } | |
| } | |
| class ActionButton extends JButton { | |
| Project project | |
| ShellAction shellAction | |
| String cmd | |
| String actionIcon | |
| ActionButton(Project _project, ShellAction _shellAction) { | |
| super(_shellAction.label, IconLoader.getIcon(_shellAction.icon)) | |
| project = _project | |
| shellAction = _shellAction | |
| addActionListener({ click() } as AbstractAction) | |
| } | |
| void click() { | |
| String cwd = shellAction.cwd ? shellAction.cwd : project.getBaseDir().getPath() | |
| TerminalView.getInstance(project) | |
| .createLocalShellWidget(cwd, shellAction.label) | |
| .executeCommand(shellAction.command) | |
| } | |
| } | |
| Configuration configuration = getConfiguration(project) | |
| if(!configuration){ | |
| return; | |
| } | |
| registerToolWindow("DXCompanion", pluginDisposable) { | |
| initPlugin(project, configuration) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment