backport: 17.0.0
This commit is contained in:
parent
62d3771a75
commit
7f15b256e6
19 changed files with 523 additions and 11 deletions
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -17,6 +17,25 @@ Changelog structure reference:
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [17.0.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Project
|
||||
- Zig Build integrated into an IDE tool window. Currently only supports running single steps, for more complex steps,
|
||||
create a custom build configuration as before.
|
||||
|
||||
### Changed
|
||||
|
||||
- Project
|
||||
- Increased internal zig tool timeout to 10 seconds. Note that tasks don't have timeout, this is only used for
|
||||
ZigBrains getting metadata about the compiler and the buildscript.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Project
|
||||
- Toolchain working directory was not set when requesting compiler metadata
|
||||
|
||||
## [16.1.3]
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -14,7 +14,7 @@ plugins {
|
|||
java
|
||||
`maven-publish`
|
||||
`java-library`
|
||||
id("org.jetbrains.intellij.platform") version("2.0.0-rc1")
|
||||
id("org.jetbrains.intellij.platform") version("2.0.0")
|
||||
id("org.jetbrains.changelog") version("2.2.1")
|
||||
id("org.jetbrains.grammarkit") version("2022.3.2.2")
|
||||
id("de.undercouch.download") version("5.6.0")
|
||||
|
|
|
@ -11,7 +11,7 @@ baseIDE=clion
|
|||
ideaVersion=2024.1.4
|
||||
clionVersion=2024.1.4
|
||||
|
||||
pluginVersion=16.1.3
|
||||
pluginVersion=17.0.0
|
||||
|
||||
# Gradle Releases -> https://github.com/gradle/gradle/releases
|
||||
gradleVersion=8.9
|
||||
|
|
|
@ -24,3 +24,11 @@ settings.debugger.toolchain.update.comment=Need to be <a>updated</a>
|
|||
settings.debugger.toolchain.use.clion.toolchains=Use Clion toolchains instead
|
||||
notification.content.debugger.need.download=You need to download/update the debugger before you can run debugging! (Settings | Build, Execution, Deployment | Debugging -> Zig)
|
||||
unable.to.run.debugger=Unable to Run Debugger
|
||||
toolwindow.stripe.zigbrains.build=Zig Build
|
||||
build.tool.window.tree.steps.label=Steps
|
||||
build.tool.window.status.not-scanned=Build steps not yet scanned. Click the refresh button.
|
||||
build.tool.window.status.loading=Running zig build -l
|
||||
build.tool.window.status.error.missing-build-zig=No build.zig file found
|
||||
build.tool.window.status.error.missing-toolchain=No zig toolchain configured
|
||||
build.tool.window.status.error.general=Error while running zig build -l
|
||||
build.tool.window.status.timeout=zig build -l timed out after {0} seconds.
|
|
@ -149,8 +149,23 @@ The <a href="https://github.com/Zigtools/ZLS">Zig Language Server</a>, for ZigBr
|
|||
<analyzeStacktraceFilter implementation="com.falsepattern.zigbrains.project.console.ZigSourceFileFilter"/>
|
||||
|
||||
<additionalLibraryRootsProvider implementation="com.falsepattern.zigbrains.project.toolchain.stdlib.ZigLibraryRootProvider"/>
|
||||
|
||||
<toolWindow factoryClass="com.falsepattern.zigbrains.project.steps.ui.BuildToolWindowFactory"
|
||||
anchor="right"
|
||||
icon="/icons/zig_build_tool.svg"
|
||||
id="zigbrains.build"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
<action
|
||||
id="ZigBrains.Reload"
|
||||
class="com.falsepattern.zigbrains.project.steps.discovery.ZigDiscoverStepsAction"
|
||||
text="Reload Zig Build Steps"
|
||||
description="Scan the project and detect build.zig steps using the current toolchain"
|
||||
icon="AllIcons.Actions.Refresh"
|
||||
/>
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.falsepattern.zigbrains">
|
||||
<toolchainFlavour implementation="com.falsepattern.zigbrains.project.toolchain.flavours.ZigSystemPathToolchainFlavour"/>
|
||||
<toolchainProvider implementation="com.falsepattern.zigbrains.project.toolchain.LocalZigToolchainProvider"/>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
package com.falsepattern.zigbrains.project.console;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||
import com.falsepattern.zigbrains.project.util.ProjectUtil;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.filters.OpenFileHyperlinkInfo;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import kotlin.Pair;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
@ -63,7 +63,7 @@ public class ZigSourceFileFilter implements Filter {
|
|||
@Override
|
||||
public Result applyFilter(@NotNull String line, int entireLength) {
|
||||
val lineStart = entireLength - line.length();
|
||||
val projectPath = Optional.ofNullable(ProjectUtil.guessProjectDir(project)).map(VirtualFile::toNioPath).orElse(null);
|
||||
val projectPath = ProjectUtil.guessProjectDir(project);
|
||||
val results = new ArrayList<ResultItem>();
|
||||
val matcher = LEN_REGEX.matcher(line);
|
||||
while (matcher.find()) {
|
||||
|
|
|
@ -16,16 +16,15 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.execution.base;
|
||||
|
||||
import com.falsepattern.zigbrains.project.util.ProjectUtil;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.configurations.ConfigurationFactory;
|
||||
import com.intellij.execution.configurations.LocatableConfigurationBase;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtil;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.NlsActions;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import org.jdom.Element;
|
||||
|
@ -41,9 +40,7 @@ public abstract class ZigExecConfigBase<T extends ZigExecConfigBase<T>> extends
|
|||
private ZigConfigEditor.CheckboxConfigurable pty = new ZigConfigEditor.CheckboxConfigurable("pty", "Emulate Terminal", false);
|
||||
public ZigExecConfigBase(@NotNull Project project, @NotNull ConfigurationFactory factory, @Nullable String name) {
|
||||
super(project, factory, name);
|
||||
workingDirectory.setPath(getProject().isDefault() ? null : Optional.ofNullable(ProjectUtil.guessProjectDir(getProject()))
|
||||
.map(VirtualFile::toNioPath)
|
||||
.orElse(null));
|
||||
workingDirectory.setPath(getProject().isDefault() ? null : ProjectUtil.guessProjectDir(getProject()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.falsepattern.zigbrains.project.steps.discovery;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ZigDiscoverStepsAction extends AnAction {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
val project = e.getProject();
|
||||
if (project == null) return;
|
||||
ZigStepDiscoveryService.getInstance(project).triggerReload();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.falsepattern.zigbrains.project.steps.discovery;
|
||||
|
||||
import com.intellij.util.messages.Topic;
|
||||
import kotlin.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ZigStepDiscoveryListener {
|
||||
@Topic.ProjectLevel
|
||||
Topic<ZigStepDiscoveryListener> TOPIC = new Topic<>(ZigStepDiscoveryListener.class);
|
||||
|
||||
enum ErrorType {
|
||||
MissingToolchain,
|
||||
MissingBuildZig,
|
||||
GeneralError
|
||||
}
|
||||
|
||||
default void preReload() {}
|
||||
default void postReload(List<Pair<String, String>> steps) {}
|
||||
default void errorReload(ErrorType type) {}
|
||||
default void timeoutReload(int seconds) {}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package com.falsepattern.zigbrains.project.steps.discovery;
|
||||
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBundle;
|
||||
import com.falsepattern.zigbrains.project.util.ProjectUtil;
|
||||
import com.intellij.ide.impl.TrustedProjects;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.Service;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import kotlin.Pair;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@Service(Service.Level.PROJECT)
|
||||
public final class ZigStepDiscoveryService {
|
||||
private static final Logger LOG = Logger.getInstance(ZigStepDiscoveryService.class);
|
||||
private static final int DEFAULT_TIMEOUT_SEC = 10;
|
||||
|
||||
private final Project project;
|
||||
|
||||
public ZigStepDiscoveryService(Project project) {
|
||||
this.project = project;
|
||||
}
|
||||
private final AtomicBoolean reloading = new AtomicBoolean(false);
|
||||
private final AtomicBoolean reloadScheduled = new AtomicBoolean(false);
|
||||
private int CURRENT_TIMEOUT_SEC = DEFAULT_TIMEOUT_SEC;
|
||||
|
||||
private void doReload() {
|
||||
val bus = project.getMessageBus().syncPublisher(ZigStepDiscoveryListener.TOPIC);
|
||||
bus.preReload();
|
||||
try {
|
||||
val toolchain = ProjectUtil.getToolchain(project);
|
||||
if (toolchain == null) {
|
||||
bus.errorReload(ZigStepDiscoveryListener.ErrorType.MissingToolchain);
|
||||
return;
|
||||
}
|
||||
|
||||
val zig = toolchain.zig();
|
||||
val result = zig.callWithArgs(
|
||||
ProjectUtil.guessProjectDir(project), CURRENT_TIMEOUT_SEC * 1000,
|
||||
"build", "-l");
|
||||
if (result.isPresent()) {
|
||||
val res = result.get();
|
||||
if (res.getExitCode() == 0) {
|
||||
if (!res.isTimeout()) {
|
||||
CURRENT_TIMEOUT_SEC = DEFAULT_TIMEOUT_SEC;
|
||||
val lines = res.getStdoutLines();
|
||||
val steps = new ArrayList<Pair<String, String>>();
|
||||
for (val line : lines) {
|
||||
val parts = line.trim().split("\\s+", 2);
|
||||
if (parts.length == 2) {
|
||||
steps.add(new Pair<>(parts[0], parts[1]));
|
||||
} else {
|
||||
steps.add(new Pair<>(parts[0], null));
|
||||
}
|
||||
}
|
||||
bus.postReload(steps);
|
||||
} else {
|
||||
bus.timeoutReload(CURRENT_TIMEOUT_SEC);
|
||||
CURRENT_TIMEOUT_SEC *= 2;
|
||||
}
|
||||
} else if (res.getStderrLines()
|
||||
.stream()
|
||||
.anyMatch(line -> line.contains(
|
||||
"error: no build.zig file found, in the current directory or any parent directories"))) {
|
||||
bus.errorReload(ZigStepDiscoveryListener.ErrorType.MissingBuildZig);
|
||||
} else {
|
||||
bus.errorReload(ZigStepDiscoveryListener.ErrorType.GeneralError);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOG.error("Error while reloading zig build steps", t);
|
||||
}
|
||||
synchronized (reloading) {
|
||||
if (reloadScheduled.getAndSet(false)) {
|
||||
dispatchReload();
|
||||
return;
|
||||
}
|
||||
reloading.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchReload() {
|
||||
val manager = ApplicationManager.getApplication();
|
||||
manager.invokeLater(() -> {
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
manager.executeOnPooledThread(this::doReload);
|
||||
});
|
||||
}
|
||||
|
||||
public void triggerReload() {
|
||||
synchronized (reloading) {
|
||||
if (reloading.get()) {
|
||||
reloadScheduled.set(true);
|
||||
return;
|
||||
}
|
||||
reloading.set(true);
|
||||
}
|
||||
dispatchReload();
|
||||
}
|
||||
|
||||
public static ZigStepDiscoveryService getInstance(Project project) {
|
||||
return project.getService(ZigStepDiscoveryService.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.falsepattern.zigbrains.project.steps.ui;
|
||||
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.ide.util.treeView.PresentableNodeDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
public class BaseNodeDescriptor<T> extends PresentableNodeDescriptor<T> {
|
||||
private String description;
|
||||
public BaseNodeDescriptor(@Nullable Project project, String displayName, Icon displayIcon) {
|
||||
this(project, displayName, null, displayIcon);
|
||||
}
|
||||
public BaseNodeDescriptor(@Nullable Project project, String displayName, String description, Icon displayIcon) {
|
||||
super(project, null);
|
||||
setIcon(displayIcon);
|
||||
myName = displayName;
|
||||
this.description = description;
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(@NotNull PresentationData presentation) {
|
||||
presentation.setIcon(getIcon());
|
||||
presentation.addText(myName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
presentation.setTooltip(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getElement() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
package com.falsepattern.zigbrains.project.steps.ui;
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBundle;
|
||||
import com.falsepattern.zigbrains.project.execution.build.ConfigTypeBuild;
|
||||
import com.falsepattern.zigbrains.project.execution.build.ZigExecConfigBuild;
|
||||
import com.falsepattern.zigbrains.project.steps.discovery.ZigStepDiscoveryListener;
|
||||
import com.falsepattern.zigbrains.zig.Icons;
|
||||
import com.intellij.execution.ProgramRunnerUtil;
|
||||
import com.intellij.execution.RunManager;
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
||||
import com.intellij.execution.executors.DefaultRunExecutor;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.SimpleToolWindowPanel;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.ui.AnimatedIcon;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import kotlin.Pair;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BuildToolWindowContext implements Disposable {
|
||||
private static final Key<JBScrollPane> VIEWPORT = Key.create("MODEL");
|
||||
|
||||
public final DefaultMutableTreeNode rootNode;
|
||||
private final DefaultMutableTreeNode buildZig;
|
||||
|
||||
private final Project project;
|
||||
|
||||
public static void create(Project project, ToolWindow window) {
|
||||
val context = new BuildToolWindowContext(project);
|
||||
project.getMessageBus().connect(context).subscribe(ZigStepDiscoveryListener.TOPIC, context.new BuildReloadListener());
|
||||
Disposer.register(window.getDisposable(), context);
|
||||
window.getContentManager().addContent(context.createContentPanel());
|
||||
}
|
||||
|
||||
private class BuildReloadListener implements ZigStepDiscoveryListener {
|
||||
@Override
|
||||
public void preReload() {
|
||||
val viewport = getViewport(project);
|
||||
if (viewport == null)
|
||||
return;
|
||||
setViewportLoading(viewport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postReload(List<Pair<String, String>> steps) {
|
||||
buildZig.removeAllChildren();
|
||||
for (val step : steps) {
|
||||
val icon = switch (step.component1()) {
|
||||
case "install" -> AllIcons.Actions.Install;
|
||||
case "uninstall" -> AllIcons.Actions.Uninstall;
|
||||
default -> AllIcons.RunConfigurations.TestState.Run;
|
||||
};
|
||||
buildZig.add(new DefaultMutableTreeNode(new StepNodeDescriptor(project, step.component1(), step.component2(), icon)));
|
||||
}
|
||||
invokeLaterWithViewport(BuildToolWindowContext.this::setViewportTree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void errorReload(ErrorType errorType) {
|
||||
invokeLaterWithViewport(viewport -> {
|
||||
setViewportError(viewport, ZigBundle.message(switch (errorType) {
|
||||
case MissingToolchain -> "build.tool.window.status.error.missing-toolchain";
|
||||
case MissingBuildZig -> "build.tool.window.status.error.missing-build-zig";
|
||||
case GeneralError -> "build.tool.window.status.error.general";
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeoutReload(int seconds) {
|
||||
invokeLaterWithViewport(viewport -> {
|
||||
setViewportError(viewport, ZigBundle.message("build.tool.window.status.timeout", seconds));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeLaterWithViewport(Consumer<JBScrollPane> callback) {
|
||||
ToolWindowManager.getInstance(project).invokeLater(() -> {
|
||||
val viewport = getViewport(project);
|
||||
if (viewport == null)
|
||||
return;
|
||||
callback.accept(viewport);
|
||||
});
|
||||
}
|
||||
|
||||
public BuildToolWindowContext(Project project) {
|
||||
this.project = project;
|
||||
rootNode = new DefaultMutableTreeNode(new BaseNodeDescriptor<>(project, project.getName(), AllIcons.Actions.ProjectDirectory));
|
||||
buildZig = new DefaultMutableTreeNode(new BaseNodeDescriptor<>(project, ZigBundle.message("build.tool.window.tree.steps.label"), Icons.ZIG));
|
||||
rootNode.add(buildZig);
|
||||
}
|
||||
|
||||
private static @Nullable JBScrollPane getViewport(Project project) {
|
||||
val toolWindow = ToolWindowManager.getInstance(project).getToolWindow("zigbrains.build");
|
||||
if (toolWindow == null)
|
||||
return null;
|
||||
val cm = toolWindow.getContentManager();
|
||||
val content = cm.getContent(0);
|
||||
if (content == null)
|
||||
return null;
|
||||
return content.getUserData(VIEWPORT);
|
||||
}
|
||||
|
||||
private static @Nullable RunnerAndConfigurationSettings getExistingRunConfig(RunManager manager, String stepName) {
|
||||
for (val config : manager.getConfigurationSettingsList(ConfigTypeBuild.class)) {
|
||||
if (!(config.getConfiguration() instanceof ZigExecConfigBuild build))
|
||||
continue;
|
||||
val steps = build.getBuildSteps().args;
|
||||
if (steps == null || steps.length != 1)
|
||||
continue;
|
||||
if (!(Objects.equals(steps[0], stepName)))
|
||||
continue;
|
||||
return config;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setViewportTree(JBScrollPane viewport) {
|
||||
val model = new DefaultTreeModel(rootNode);
|
||||
val tree = new Tree(model);
|
||||
tree.expandPath(new TreePath(model.getPathToRoot(buildZig)));
|
||||
viewport.setViewportView(tree);
|
||||
tree.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
val node = tree.getLastSelectedPathComponent();
|
||||
if (node == null)
|
||||
return;
|
||||
if (!(node instanceof DefaultMutableTreeNode mut))
|
||||
return;
|
||||
if (!(mut.getUserObject() instanceof StepNodeDescriptor step))
|
||||
return;
|
||||
|
||||
val stepName = step.getElement().name();
|
||||
val manager = RunManager.getInstance(project);
|
||||
val config = Objects.requireNonNullElseGet(getExistingRunConfig(manager, stepName), () -> {
|
||||
val factory = ConfigTypeBuild.getInstance().getConfigurationFactories()[0];
|
||||
val newConfig = manager.createConfiguration("zig build " + stepName, factory);
|
||||
((ZigExecConfigBuild)newConfig.getConfiguration()).getBuildSteps().args = new String[]{stepName};
|
||||
manager.addConfiguration(newConfig);
|
||||
return newConfig;
|
||||
});
|
||||
|
||||
manager.setSelectedConfiguration(config);
|
||||
ProgramRunnerUtil.executeConfiguration(config, DefaultRunExecutor.getRunExecutorInstance());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setViewportLoading(JBScrollPane viewport) {
|
||||
viewport.setViewportView(new JBLabel(ZigBundle.message("build.tool.window.status.loading"), new AnimatedIcon.Default(), SwingConstants.CENTER));
|
||||
}
|
||||
|
||||
private void setViewportNoContent(JBScrollPane viewport) {
|
||||
viewport.setViewportView(new JBLabel(ZigBundle.message("build.tool.window.status.not-scanned"), AllIcons.General.Information, SwingConstants.CENTER));
|
||||
}
|
||||
|
||||
private void setViewportError(JBScrollPane viewport, String msg) {
|
||||
viewport.setViewportView(new JBLabel(msg, AllIcons.General.Error, SwingConstants.CENTER));
|
||||
}
|
||||
|
||||
private Content createContentPanel() {
|
||||
val contentPanel = new SimpleToolWindowPanel(false);
|
||||
val body = new JPanel(new GridBagLayout());
|
||||
contentPanel.setLayout(new GridBagLayout());
|
||||
val c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.weightx = 1;
|
||||
c.weighty = 1;
|
||||
contentPanel.add(body, c);
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.anchor = GridBagConstraints.NORTHWEST;
|
||||
c.weightx = 1;
|
||||
c.weighty = 0;
|
||||
val toolbar = ActionManager.getInstance().createActionToolbar("ZigToolbar", new DefaultActionGroup(ActionManager.getInstance().getAction("ZigBrains.Reload")), true);
|
||||
toolbar.setTargetComponent(null);
|
||||
body.add(toolbar.getComponent(), c);
|
||||
c.gridwidth = 1;
|
||||
c.gridy = 1;
|
||||
c.weighty = 1;
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
val viewport = new JBScrollPane();
|
||||
setViewportNoContent(viewport);
|
||||
body.add(viewport, c);
|
||||
val content = ContentFactory.getInstance().createContent(contentPanel, "", false);
|
||||
content.putUserData(VIEWPORT, viewport);
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.falsepattern.zigbrains.project.steps.ui;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BuildToolWindowFactory implements ToolWindowFactory {
|
||||
@Override
|
||||
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
|
||||
BuildToolWindowContext.create(project, toolWindow);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package com.falsepattern.zigbrains.project.steps.ui;
|
||||
|
||||
public record StepDetails(String name) {
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.falsepattern.zigbrains.project.steps.ui;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
public class StepNodeDescriptor extends BaseNodeDescriptor<StepDetails> {
|
||||
private final String stepName;
|
||||
public StepNodeDescriptor(@Nullable Project project, String stepName, String description, Icon displayIcon) {
|
||||
super(project, stepName, description, displayIcon);
|
||||
this.stepName = stepName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StepDetails getElement() {
|
||||
return new StepDetails(stepName);
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ public class LocalZigToolchain extends AbstractZigToolchain{
|
|||
|
||||
@Override
|
||||
public int executionTimeoutInMilliseconds() {
|
||||
return 1000;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,7 +37,7 @@ public class ZigCompilerTool extends AbstractZigTool{
|
|||
public ZigCompilerTool(AbstractZigToolchain toolchain) {
|
||||
super(toolchain, TOOL_NAME);
|
||||
val app = ApplicationManager.getApplication();
|
||||
val baseFuture = app.executeOnPooledThread(() -> getEnv(null));
|
||||
val baseFuture = app.executeOnPooledThread(() -> getEnv(toolchain.getLocation()));
|
||||
version = new Lazy<>(() -> {
|
||||
try {
|
||||
return baseFuture.get().map(ZigToolchainEnvironmentSerializable::version);
|
||||
|
|
|
@ -19,11 +19,21 @@ package com.falsepattern.zigbrains.project.util;
|
|||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ProjectUtil {
|
||||
public static @Nullable AbstractZigToolchain getToolchain(Project project) {
|
||||
return ZigProjectSettingsService.getInstance(project).getState().getToolchain();
|
||||
}
|
||||
|
||||
public static @Nullable Path guessProjectDir(Project project) {
|
||||
val dir = com.intellij.openapi.project.ProjectUtil.guessProjectDir(project);
|
||||
if (dir == null)
|
||||
return null;
|
||||
return dir.toNioPath();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
21
modules/project/src/main/resources/icons/zig_build_tool.svg
Normal file
21
modules/project/src/main/resources/icons/zig_build_tool.svg
Normal file
|
@ -0,0 +1,21 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 154 140">
|
||||
<g fill="#AFB1B3">
|
||||
<g>
|
||||
<polygon points="46,22 28,44 19,30"/>
|
||||
<polygon points="46,22 33,33 28,44 22,44 22,95 31,95 20,100 12,117 0,117 0,22" shape-rendering="crispEdges"/>
|
||||
<polygon points="31,95 12,117 4,106"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon points="56,22 62,36 37,44"/>
|
||||
<polygon points="56,22 111,22 111,44 37,44 56,32" shape-rendering="crispEdges"/>
|
||||
<polygon points="116,95 97,117 90,104"/>
|
||||
<polygon points="116,95 100,104 97,117 42,117 42,95" shape-rendering="crispEdges"/>
|
||||
<polygon points="150,0 52,117 3,140 101,22"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon points="141,22 140,40 122,45"/>
|
||||
<polygon points="153,22 153,117 106,117 120,105 125,95 131,95 131,45 122,45 132,36 141,22" shape-rendering="crispEdges"/>
|
||||
<polygon points="125,95 130,110 106,117"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 850 B |
Loading…
Add table
Reference in a new issue