diff --git a/src/main/java/icons/BldIcons.java b/src/main/java/icons/BldIcons.java new file mode 100644 index 0000000..68bfbc8 --- /dev/null +++ b/src/main/java/icons/BldIcons.java @@ -0,0 +1,17 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package icons; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class BldIcons { + private static javax.swing.Icon load(String path) { + return IconLoader.getIcon(path, BldIcons.class); + } + + public static final Icon Icon = load("/icons/bldIcon.svg"); +} diff --git a/src/main/java/rife/bld/idea/ProjectOpenStartupActivity.java b/src/main/java/rife/bld/idea/ProjectOpenStartupActivity.java new file mode 100644 index 0000000..1d18a7f --- /dev/null +++ b/src/main/java/rife/bld/idea/ProjectOpenStartupActivity.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package rife.bld.idea; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.ProjectActivity; +import kotlin.Unit; +import kotlin.coroutines.Continuation; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import rife.bld.idea.execution.BldExecution; + +public class ProjectOpenStartupActivity implements ProjectActivity { + @Nullable + @Override + public Object execute(@NotNull Project project, @NotNull Continuation continuation) { + System.out.println("Startup"); + + BldExecution.listTasks(project); + + /* Clear console window. */ +// ApplicationManager.getApplication().invokeAndWait(() -> { +// ConsoleView executionConsole = BldConsoleManager.getConsole(project); +// executionConsole.getComponent().setVisible(true); +// executionConsole.clear(); +// var console = ToolWindowManagerEx.getInstance(project).getToolWindow(BldConstants.BLD_CONSOLE_NAME); +// if (console != null) { +// console.activate(null); +// } +// }, ModalityState.nonModal()); + + return null; + } +} diff --git a/src/main/java/rife/bld/idea/console/BldConsoleManager.java b/src/main/java/rife/bld/idea/console/BldConsoleManager.java new file mode 100644 index 0000000..104e3ba --- /dev/null +++ b/src/main/java/rife/bld/idea/console/BldConsoleManager.java @@ -0,0 +1,69 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package rife.bld.idea.console; + +import com.intellij.execution.filters.Filter; +import com.intellij.execution.filters.TextConsoleBuilderFactory; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import org.jetbrains.annotations.NotNull; +import rife.bld.idea.utils.BldPluginDisposable; + +public class BldConsoleManager { + private final ConsoleView bldConsole_; + + public BldConsoleManager(@NotNull Project project) { + bldConsole_ = createNewConsole(project); + Disposer.register(BldPluginDisposable.getInstance(project), bldConsole_); + } + + private static ConsoleView createNewConsole(@NotNull Project project) { + return TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole(); + } + + public static ConsoleView getConsole(@NotNull Project project) { + var service = project.getService(BldConsoleManager.class); + return service.getConsole(); + } + + public ConsoleView getConsole() { + return bldConsole_; + } + + public static void showTaskMessage(@NotNull String message, @NotNull ConsoleViewContentType type, @NotNull Project project) { + var executionConsole = BldConsoleManager.getConsole(project); + // Create a filter that monitors console outputs, and turns them into a hyperlink if applicable. + Filter filter = (line, entireLength) -> { +// Optional result = ParseResult.parseErrorLocation(line, ERROR_TAG); +// if (result.isPresent()) { +// +// OpenFileHyperlinkInfo linkInfo = new OpenFileHyperlinkInfo( +// project, +// result.get().getFile(), +// result.get().getLineNumber() - 1, // line number needs to be 0 indexed +// result.get().getColumnNumber() - 1 // column number needs to be 0 indexed +// ); +// int startHyperlink = entireLength - line.length() + line.indexOf(ERROR_TAG); +// +// return new Filter.Result( +// startHyperlink, +// entireLength, +// linkInfo, +// null // TextAttributes, going with default hence null +// ); +// } + return null; + }; + + ApplicationManager.getApplication().invokeLater(() -> { + executionConsole.addMessageFilter(filter); + executionConsole.print(message, type); + }, ModalityState.nonModal()); + } +} diff --git a/src/main/java/rife/bld/idea/console/BldConsoleViewPanel.java b/src/main/java/rife/bld/idea/console/BldConsoleViewPanel.java new file mode 100644 index 0000000..0f2ccce --- /dev/null +++ b/src/main/java/rife/bld/idea/console/BldConsoleViewPanel.java @@ -0,0 +1,135 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package rife.bld.idea.console; + +import com.intellij.execution.ui.ConsoleView; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.icons.AllIcons; +import com.intellij.ide.IdeBundle; +import com.intellij.ide.errorTreeView.NewErrorTreeRenderer; +import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.ui.AutoScrollToSourceHandler; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.SideBorder; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.ui.tree.TreeUtil; +import org.jetbrains.annotations.NotNull; +import rife.bld.idea.execution.BldExecution; +import rife.bld.idea.utils.BldBundle; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.awt.*; + +public class BldConsoleViewPanel extends JPanel { + protected static final Logger LOG = Logger.getInstance("#com.intellij.ide.errorTreeView.NewErrorTreeViewPanel"); + + private final ErrorTreeViewConfiguration configuration_; + protected Project project_; + + public BldConsoleViewPanel(Project project, ConsoleView console) { + project_ = project; + configuration_ = ErrorTreeViewConfiguration.getInstance(project); + setLayout(new BorderLayout()); + + AutoScrollToSourceHandler auto_scroll_to_source = new AutoScrollToSourceHandler() { + @Override + protected boolean isAutoScrollMode() { + return configuration_.isAutoscrollToSource(); + } + + @Override + protected void setAutoScrollMode(boolean state) { + configuration_.setAutoscrollToSource(state); + } + }; + + var message_panel = new JPanel(new BorderLayout()); + + var root = new DefaultMutableTreeNode(); + final var tree_model = new DefaultTreeModel(root); + var tree = createTree(tree_model); + tree.getEmptyText().setText(IdeBundle.message("errortree.noMessages")); + + auto_scroll_to_source.install(tree); + TreeUtil.installActions(tree); + + tree.setRootVisible(false); + tree.setShowsRootHandles(true); + tree.setLargeModel(true); + + var scroll_pane = NewErrorTreeRenderer.install(tree); + scroll_pane.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT)); + message_panel.add(console.getComponent(), BorderLayout.CENTER); + + add(createToolbarPanel(), BorderLayout.WEST); + + add(message_panel, BorderLayout.CENTER); + + EditSourceOnDoubleClickHandler.install(tree); + } + + @NotNull + protected Tree createTree(@NotNull final DefaultTreeModel treeModel) { + return new Tree(treeModel) { + @Override + public void setRowHeight(int i) { + super.setRowHeight(0); + // this is needed in order to make UI calculate the height for each particular row + } + }; + } + + private static class StopAction extends DumbAwareAction { + public StopAction() { + super(IdeBundle.message("action.stop"), null, AllIcons.Actions.Suspend); + } + + @Override + public void actionPerformed(AnActionEvent e) { + var project = e.getProject(); + if (project != null) { + BldExecution.terminateBldProcess(project); + BldConsoleManager.getConsole(project).print(BldBundle.message("bld.command.terminated"), ConsoleViewContentType.ERROR_OUTPUT); + } + } + + @Override + public void update(AnActionEvent event) { + // Make the action only clickable when there is an active bld process + var presentation = event.getPresentation(); + var project = event.getProject(); + if (project == null) { + return; + } + presentation.setEnabled(BldExecution.hasActiveBldProcess(project)); + } + + @Override + public @NotNull ActionUpdateThread getActionUpdateThread() { + return ActionUpdateThread.BGT; + } + } + + private JPanel createToolbarPanel() { + var action = new StopAction(); + + var group = new DefaultActionGroup(); + group.add(action); + + var toolbar_panel = new JPanel(new BorderLayout()); + var action_manager = ActionManager.getInstance(); + var let_toolbar = action_manager.createActionToolbar(ActionPlaces.COMPILER_MESSAGES_TOOLBAR, group, false); + toolbar_panel.add(let_toolbar.getComponent(), BorderLayout.WEST); + + return toolbar_panel; + } +} diff --git a/src/main/java/rife/bld/idea/console/BldConsoleWindowFactory.java b/src/main/java/rife/bld/idea/console/BldConsoleWindowFactory.java new file mode 100644 index 0000000..1f17089 --- /dev/null +++ b/src/main/java/rife/bld/idea/console/BldConsoleWindowFactory.java @@ -0,0 +1,21 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package rife.bld.idea.console; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.ui.content.ContentFactory; +import org.jetbrains.annotations.NotNull; + +public class BldConsoleWindowFactory implements ToolWindowFactory { + @Override + public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { + var console = BldConsoleManager.getConsole(project); + var window = new BldConsoleViewPanel(project, console); + var content = ContentFactory.getInstance().createContent(window, null, false); + toolWindow.getContentManager().addContent(content); + } +} \ No newline at end of file diff --git a/src/main/java/rife/bld/idea/execution/BldExecution.java b/src/main/java/rife/bld/idea/execution/BldExecution.java new file mode 100644 index 0000000..5732ff6 --- /dev/null +++ b/src/main/java/rife/bld/idea/execution/BldExecution.java @@ -0,0 +1,128 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package rife.bld.idea.execution; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.process.CapturingAnsiEscapesAwareProcessHandler; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectUtil; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import rife.bld.idea.console.BldConsoleManager; +import rife.bld.idea.utils.BldConstants; +import rife.bld.wrapper.Wrapper; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class BldExecution { + private static final ConcurrentHashMap runningBldProcesses_ = new ConcurrentHashMap<>(); + + public BldExecution(@NotNull Project project) { + } + + public static boolean hasActiveBldProcess(@NotNull Project project) { + return runningBldProcesses_.containsKey(project); + } + + public static void terminateBldProcess(Project project) { + var process = runningBldProcesses_.get(project); + if (process != null) { + process.destroy(); + runningBldProcesses_.remove(project, process); + } + } + + public static void listTasks(@NotNull Project project) { + executeCommands(project, (String[]) null); + } + + public static void executeCommands(@NotNull Project project, String... commands) { + var project_dir = ProjectUtil.guessProjectDir(project); + if (project_dir == null) { + BldConsoleManager.showTaskMessage("Could not find project directory\n", ConsoleViewContentType.ERROR_OUTPUT, project); + } + else { + var bldMainClass = guessBldMainClass(project, project_dir); + if (bldMainClass == null) { + BldConsoleManager.showTaskMessage("Could not find bld main class for project " + project_dir + "\n", ConsoleViewContentType.ERROR_OUTPUT, project); + } + else { + BldConsoleManager.showTaskMessage("Found bld main class: " + bldMainClass + "\n", ConsoleViewContentType.SYSTEM_OUTPUT, project); + + final var command_line = new GeneralCommandLine(); + command_line.setWorkDirectory(project_dir.getCanonicalPath()); + command_line.setExePath("java"); + command_line.addParameter("-jar"); + command_line.addParameter(project_dir.getCanonicalPath() + "/lib/bld/bld-wrapper.jar"); + command_line.addParameter(project_dir.getCanonicalPath() + "/bld"); + command_line.addParameter(Wrapper.BUILD_ARGUMENT); + command_line.addParameter(bldMainClass); + command_line.addParameter(Wrapper.JSON_ARGUMENT); + if (commands != null) { + command_line.addParameters(commands); + } + + final Process process; + try { + process = command_line.createProcess(); + } + catch (ExecutionException e) { + BldConsoleManager.showTaskMessage(e.getMessage() != null ? e.getMessage() : e.toString(), ConsoleViewContentType.ERROR_OUTPUT, project); + return; + } + + final var output = runBldProcess(project, process, command_line); + + } + } + } + + private static @NotNull List runBldProcess(@NotNull Project project, @NotNull Process process, @NotNull GeneralCommandLine commandLine) { + final var process_handler = new CapturingAnsiEscapesAwareProcessHandler(process, commandLine.getCommandLineString()); + final var output = new ArrayList(); + process_handler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { + super.onTextAvailable(event, outputType); + BldConsoleManager.showTaskMessage(event.getText(), ConsoleViewContentType.NORMAL_OUTPUT, project); + output.add(event.getText()); + } + }); + + runningBldProcesses_.put(project, process); + process_handler.runProcess(); + runningBldProcesses_.remove(project, process); + + return output; + } + + private static String guessBldMainClass(@NotNull Project project, @NotNull VirtualFile projectDir) { + var project_bld = projectDir.findChild("bld"); + if (project_bld == null) { + project_bld = projectDir.findChild("bld.bat"); + } + if (project_bld != null) { + try { + var contents = new String(project_bld.contentsToByteArray()); + var matcher = BldConstants.BUILD_MAIN_CLASS.matcher(contents); + if (matcher.find()) { + return matcher.group(1); + } + } catch (IOException e) { + BldConsoleManager.showTaskMessage("Unable to read contents of " + project_bld + "\n", ConsoleViewContentType.ERROR_OUTPUT, project); + } + } + return null; + } + +} diff --git a/src/main/java/rife/bld/idea/listeners/BldApplicationActivationListener.java b/src/main/java/rife/bld/idea/listeners/BldApplicationActivationListener.java index c99eeb3..d7c2ce4 100644 --- a/src/main/java/rife/bld/idea/listeners/BldApplicationActivationListener.java +++ b/src/main/java/rife/bld/idea/listeners/BldApplicationActivationListener.java @@ -1,3 +1,7 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ package rife.bld.idea.listeners; import com.intellij.openapi.application.ApplicationActivationListener; diff --git a/src/main/java/rife/bld/idea/toolWindow/BldToolWindowFactory.java b/src/main/java/rife/bld/idea/toolWindow/BldToolWindowFactory.java index 2687b99..be04a8a 100644 --- a/src/main/java/rife/bld/idea/toolWindow/BldToolWindowFactory.java +++ b/src/main/java/rife/bld/idea/toolWindow/BldToolWindowFactory.java @@ -1,94 +1,53 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ package rife.bld.idea.toolWindow; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowFactory; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBPanel; import com.intellij.ui.content.ContentFactory; import org.jetbrains.annotations.NotNull; -import rife.bld.wrapper.Wrapper; -import rife.tools.ExceptionUtils; +import javax.swing.*; import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Objects; -import java.util.regex.Pattern; -public class BldToolWindowFactory implements ToolWindowFactory { +public class BldToolWindowFactory implements ToolWindowFactory, DumbAware { @Override public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { var window = new BldToolWindow(toolWindow); - var content = ContentFactory.getInstance().createContent(window.getContent(), null, false); + var content = ContentFactory.getInstance().createContent(window.getContentPanel(), null, false); toolWindow.getContentManager().addContent(content); } - static class BldToolWindow { - public BldToolWindow(ToolWindow toolWindow) { - var project = toolWindow.getProject(); - var project_dir = ProjectUtil.guessProjectDir(project); - if (project_dir == null) { - Logger.getInstance(BldToolWindowFactory.class).warn("Could not find project directory"); - } - else { - var bldMainClass = guessBldMainClass(project_dir); - if (bldMainClass == null) { - Logger.getInstance(BldToolWindowFactory.class).warn("Unable to determine bld's main class for project"); - } - else { - var java_args = new ArrayList(); - java_args.add("java"); - java_args.add("-jar"); - java_args.add(project_dir.getCanonicalPath() + "/lib/bld/bld-wrapper.jar"); - java_args.add(project_dir.getCanonicalPath() + "/bld"); - java_args.add(Wrapper.BUILD_ARGUMENT); - java_args.add(bldMainClass); - java_args.add(Wrapper.JSON_ARGUMENT); - - var process_builder = new ProcessBuilder(java_args); - process_builder.directory(new File(Objects.requireNonNull(project_dir.getCanonicalPath()))); - process_builder.inheritIO(); + private static class BldToolWindow { + private final JBPanel contentPanel_; - try { - var process = process_builder.start(); - process.waitFor(); - } catch (IOException | InterruptedException e) { - Logger.getInstance(BldToolWindowFactory.class).warn("Unable to launch bld wrapper: " + ExceptionUtils.getExceptionStackTrace(e)); - } - } - } + public BldToolWindow(ToolWindow toolWindow) { + contentPanel_ = new JBPanel<>(new BorderLayout()); + contentPanel_.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + contentPanel_.add(createControlsPanel(toolWindow), BorderLayout.NORTH); + contentPanel_.add(new JBLabel("This is the bld tool window"), BorderLayout.CENTER); } - private final static Pattern BUILD_MAIN_CLASS = Pattern.compile(Wrapper.BUILD_ARGUMENT + "\\s(\\S+)");; - - public String guessBldMainClass(VirtualFile projectDir) { - if (projectDir != null) { - var project_bld = projectDir.findChild("bld"); - if (project_bld == null) { - project_bld = projectDir.findChild("bld.bat"); - } - if (project_bld != null) { - try { - var contents = new String(project_bld.contentsToByteArray()); - var matcher = BUILD_MAIN_CLASS.matcher(contents); - if (matcher.find()) return matcher.group(1); - } catch (IOException e) { - Logger.getInstance(BldToolWindowFactory.class).warn("Unable to read contents of " + project_bld); - } - } - } - return null; + public JBPanel getContentPanel() { + return contentPanel_; } - public JBPanel getContent() { - var panel = new JBPanel<>(new BorderLayout()); - panel.add(new JBLabel("This is the bld tool window")); - return panel; + @NotNull + private JPanel createControlsPanel(ToolWindow toolWindow) { + var controlsPanel = new JPanel(); + var refreshDateAndTimeButton = new JButton("Refresh"); + refreshDateAndTimeButton.addActionListener(e -> {}); + controlsPanel.add(refreshDateAndTimeButton); + var hideToolWindowButton = new JButton("Hide"); + hideToolWindowButton.addActionListener(e -> toolWindow.hide(null)); + controlsPanel.add(hideToolWindowButton); + return controlsPanel; } } } diff --git a/src/main/java/rife/bld/idea/utils/BldBundle.java b/src/main/java/rife/bld/idea/utils/BldBundle.java new file mode 100644 index 0000000..de30b68 --- /dev/null +++ b/src/main/java/rife/bld/idea/utils/BldBundle.java @@ -0,0 +1,32 @@ +package rife.bld.idea.utils; + +import com.intellij.AbstractBundle; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.PropertyKey; + +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.util.ResourceBundle; + +public class BldBundle { + private static Reference ourBundle; + + @NonNls + private static final String BUNDLE = "messages.BldBundle"; + + public static String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) { + return AbstractBundle.message(getBundle(), key, params); + } + + private static ResourceBundle getBundle() { + ResourceBundle bundle = null; + + if (ourBundle != null) bundle = ourBundle.get(); + + if (bundle == null) { + bundle = ResourceBundle.getBundle(BUNDLE); + ourBundle = new SoftReference<>(bundle); + } + return bundle; + } +} diff --git a/src/main/java/rife/bld/idea/utils/BldConstants.java b/src/main/java/rife/bld/idea/utils/BldConstants.java new file mode 100644 index 0000000..de3d684 --- /dev/null +++ b/src/main/java/rife/bld/idea/utils/BldConstants.java @@ -0,0 +1,15 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package rife.bld.idea.utils; + +import rife.bld.wrapper.Wrapper; + +import java.util.regex.Pattern; + +public class BldConstants { + public static final String BLD = "bld"; + public static final String CONSOLE_NAME = "Bld Console"; + public static final Pattern BUILD_MAIN_CLASS = Pattern.compile(Wrapper.BUILD_ARGUMENT + "\\s(\\S+)");; +} diff --git a/src/main/java/rife/bld/idea/utils/BldPluginDisposable.java b/src/main/java/rife/bld/idea/utils/BldPluginDisposable.java new file mode 100644 index 0000000..883d0f8 --- /dev/null +++ b/src/main/java/rife/bld/idea/utils/BldPluginDisposable.java @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com) + * Licensed under the Apache License, Version 2.0 (the "License") + */ +package rife.bld.idea.utils; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.Service; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +/** + * The service is intended to be used instead of a project/application as a parent disposable. + */ +@Service({Service.Level.APP, Service.Level.PROJECT}) +public final class BldPluginDisposable implements Disposable { + public static @NotNull Disposable getInstance() { + return ApplicationManager.getApplication().getService(BldPluginDisposable.class); + } + + public static @NotNull Disposable getInstance(@NotNull Project project) { + return project.getService(BldPluginDisposable.class); + } + + @Override + public void dispose() { + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 0118224..ab96969 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -9,7 +9,11 @@ messages.BldBundle - + + + + + diff --git a/src/main/resources/icons/bldIcon.svg b/src/main/resources/icons/bldIcon.svg new file mode 100644 index 0000000..81220b4 --- /dev/null +++ b/src/main/resources/icons/bldIcon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/main/resources/messages/BldBundle.properties b/src/main/resources/messages/BldBundle.properties index d056307..136521e 100644 --- a/src/main/resources/messages/BldBundle.properties +++ b/src/main/resources/messages/BldBundle.properties @@ -1,3 +1,4 @@ name=bld applicationService=Application service -projectService=Project service: {0} \ No newline at end of file +projectService=Project service: {0} +bld.command.terminated=\nbld command was terminated\!