backport: 14.2.0
This commit is contained in:
parent
5328d6f498
commit
ae660ccb1e
13 changed files with 327 additions and 26 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -17,6 +17,18 @@ Changelog structure reference:
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [14.2.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Zig
|
||||
- External Libraries support for zig stdlib
|
||||
|
||||
### Fixed
|
||||
|
||||
- Debugging (Windows)
|
||||
- Variables sometimes don't show up in the variable inspector when in breakpoint state
|
||||
|
||||
## [14.1.0]
|
||||
|
||||
### Fixed
|
||||
|
|
22
README.md
22
README.md
|
@ -1,8 +1,26 @@
|
|||
# ZigBrains
|
||||
|
||||
### [Website](https://falsepattern.com/zigbrains)
|
||||
Zig language support for IntelliJ IDEA, CLion, and other JetBrains IDEs.
|
||||
|
||||
### [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/22456-zigbrains)
|
||||
## Installing
|
||||
|
||||
You can either install this plugin from the [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/22456-zigbrains), or from FalsePattern's [website](https://falsepattern.com/zigbrains).
|
||||
|
||||
See [the quick setup guide](#quick-setup-guide-for-zig-and-zls) for how to set up language server integration.
|
||||
|
||||
Note: marketplace updates are usually delayed by a few days from the actual release, so if you want to always have the
|
||||
latest builds of ZigBrains, you can set up your IDE to download signed releases directly from FalsePattern's website
|
||||
through the built-in plugin browser:
|
||||
|
||||
1. Go to `Settings -> Plugins`
|
||||
2. To the right of the `Installed` button at the top, click on the `...` dropdown menu, then select `Manage Plugin Repositories...`
|
||||
3. Click the add button, and then enter the ZigBrains updater URL, based on your IDE version:
|
||||
- `2024.1.*`: https://falsepattern.com/zigbrains/updatePlugins-241.xml
|
||||
- `2023.3.*`: https://falsepattern.com/zigbrains/updatePlugins-233.xml
|
||||
- `2023.2.*`: https://falsepattern.com/zigbrains/updatePlugins-232.xml
|
||||
- `2023.1.*`: https://falsepattern.com/zigbrains/updatePlugins-231.xml
|
||||
4. Click `OK`, and your IDE should now automatically detect the latest version
|
||||
(both in the Installed tab and in the Marketplace tab), even if it's not yet verified on the official JetBrains marketplace yet.
|
||||
|
||||
## Developer guide
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.common.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class Lazy<T> {
|
||||
private T value;
|
||||
|
||||
private final Supplier<T> initializer;
|
||||
|
||||
public T get() {
|
||||
if (value != null)
|
||||
return value;
|
||||
|
||||
synchronized (this) {
|
||||
if (value != null)
|
||||
return value;
|
||||
return value = initializer.get();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -856,16 +856,11 @@ public abstract class DAPDriver<
|
|||
*/
|
||||
@Override
|
||||
public @NotNull LLValueData getData(@NotNull LLValue value) throws ExecutionException, DebuggerCommandException {
|
||||
String result;
|
||||
String result = "";
|
||||
int childrenRef = 0;
|
||||
boolean failed = false;
|
||||
if (value.getReferenceExpression().isBlank()) {
|
||||
val known = value.getUserData(LLVALUE_DATA);
|
||||
if (known != null)
|
||||
return known;
|
||||
val cRef = value.getUserData(LLVALUE_CHILDREN_REF);
|
||||
if (cRef != null)
|
||||
childrenRef = cRef;
|
||||
result = "";
|
||||
failed = true;
|
||||
} else {
|
||||
val args = new EvaluateArguments();
|
||||
args.setContext(EvaluateArgumentsContext.VARIABLES);
|
||||
|
@ -875,8 +870,27 @@ public abstract class DAPDriver<
|
|||
childrenRef = res.getVariablesReference();
|
||||
if (childrenRef > 0)
|
||||
value.putUserData(LLVALUE_CHILDREN_REF, childrenRef);
|
||||
val hint = res.getPresentationHint();
|
||||
if (hint != null) {
|
||||
val attribs = hint.getAttributes();
|
||||
if (attribs != null) {
|
||||
for (val attrib: attribs) {
|
||||
if ("failedEvaluation".equals(attrib)) {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = res.getResult();
|
||||
}
|
||||
if (failed) {
|
||||
val known = value.getUserData(LLVALUE_DATA);
|
||||
if (known != null)
|
||||
return known;
|
||||
val cRef = value.getUserData(LLVALUE_CHILDREN_REF);
|
||||
if (cRef != null)
|
||||
childrenRef = cRef;
|
||||
}
|
||||
return new LLValueData(result, null, false, childrenRef > 0, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.falsepattern.zigbrains.lsp.statusbar.LSPServerStatusWidget;
|
|||
import com.falsepattern.zigbrains.lsp.statusbar.LSPServerStatusWidgetFactory;
|
||||
import com.falsepattern.zigbrains.lsp.utils.FileUtils;
|
||||
import com.falsepattern.zigbrains.lsp.utils.LSPException;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.openapi.application.ApplicationInfo;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
|
@ -514,16 +515,28 @@ public class LanguageServerWrapper {
|
|||
Class<? extends LanguageServer> remoteServerInterFace = extManager.getExtendedServerInterface();
|
||||
client = extManager.getExtendedClientFor(new ServerWrapperBaseClientContext(this));
|
||||
|
||||
Launcher<? extends LanguageServer> launcher = Launcher
|
||||
.createLauncher(client, remoteServerInterFace, inputStream, outputStream, executorService,
|
||||
messageHandler);
|
||||
val launcher = new Launcher.Builder<LanguageServer>()
|
||||
.setLocalService(client)
|
||||
.setRemoteInterface(remoteServerInterFace)
|
||||
.setInput(inputStream)
|
||||
.setOutput(outputStream)
|
||||
.setExecutorService(executorService)
|
||||
.wrapMessages(messageHandler)
|
||||
.configureGson(GsonBuilder::disableHtmlEscaping)
|
||||
.create();
|
||||
languageServer = launcher.getRemoteProxy();
|
||||
launcherFuture = launcher.startListening();
|
||||
} else {
|
||||
client = new DefaultLanguageClient(new ServerWrapperBaseClientContext(this));
|
||||
Launcher<LanguageServer> launcher = Launcher
|
||||
.createLauncher(client, LanguageServer.class, inputStream, outputStream, executorService,
|
||||
messageHandler);
|
||||
val launcher = new Launcher.Builder<LanguageServer>()
|
||||
.setLocalService(client)
|
||||
.setRemoteInterface(LanguageServer.class)
|
||||
.setInput(inputStream)
|
||||
.setOutput(outputStream)
|
||||
.setExecutorService(executorService)
|
||||
.wrapMessages(messageHandler)
|
||||
.configureGson(GsonBuilder::disableHtmlEscaping)
|
||||
.create();
|
||||
languageServer = launcher.getRemoteProxy();
|
||||
launcherFuture = launcher.startListening();
|
||||
}
|
||||
|
@ -559,8 +572,13 @@ public class LanguageServerWrapper {
|
|||
private InitializeParams getInitParams() throws URISyntaxException {
|
||||
InitializeParams initParams = new InitializeParams();
|
||||
String projectRootUri = FileUtil.pathToUri(projectRootPath);
|
||||
if (projectRootUri.endsWith("/")) {
|
||||
projectRootUri = projectRootUri.substring(0, projectRootUri.length() - 1);
|
||||
}
|
||||
WorkspaceFolder workspaceFolder = new WorkspaceFolder(projectRootUri, this.project.getName());
|
||||
initParams.setWorkspaceFolders(Collections.singletonList(workspaceFolder));
|
||||
initParams.setProcessId((int) ProcessHandle.current().pid());
|
||||
initParams.setLocale("en-us");
|
||||
|
||||
// workspace capabilities
|
||||
WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities();
|
||||
|
|
|
@ -44,7 +44,7 @@ public class DocumentEventManager {
|
|||
private final TextDocumentSyncKind syncKind;
|
||||
private final LanguageServerWrapper wrapper;
|
||||
private final TextDocumentIdentifier identifier;
|
||||
private int version = -1;
|
||||
private int version = 0;
|
||||
protected Logger LOG = Logger.getInstance(EditorEventManager.class);
|
||||
|
||||
private final Set<Document> openDocuments = new HashSet<>();
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettings;
|
|||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider;
|
||||
import com.falsepattern.zigbrains.project.toolchain.tools.ZigCompilerTool;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
|
@ -114,8 +115,8 @@ public class ZigProjectSettingsPanel implements MyDisposable {
|
|||
() -> {
|
||||
val toolchain = Optional.ofNullable(pathToToolchain).map(ZigToolchainProvider::findToolchain).orElse(null);
|
||||
val zig = Optional.ofNullable(toolchain).map(AbstractZigToolchain::zig).orElse(null);
|
||||
val version = Optional.ofNullable(zig).flatMap(z -> z.queryVersion(Path.of("."))).orElse(null);
|
||||
val stdPath = Optional.ofNullable(zig).flatMap(z -> z.getStdPath(Path.of("."))).orElse(null);
|
||||
val version = Optional.ofNullable(zig).flatMap(ZigCompilerTool::queryVersion).orElse(null);
|
||||
val stdPath = Optional.ofNullable(zig).flatMap(ZigCompilerTool::getStdPath).orElse(null);
|
||||
|
||||
return new Pair<>(version, stdPath);
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.toolchain;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.Lazy;
|
||||
import com.falsepattern.zigbrains.project.toolchain.flavours.AbstractZigToolchainFlavour;
|
||||
import com.falsepattern.zigbrains.project.toolchain.tools.ZigCompilerTool;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
|
@ -31,6 +32,8 @@ import java.util.Objects;
|
|||
public abstract class AbstractZigToolchain {
|
||||
private final Path location;
|
||||
|
||||
private final Lazy<ZigCompilerTool> zig = new Lazy<>(() -> new ZigCompilerTool(this));
|
||||
|
||||
public static @Nullable AbstractZigToolchain suggest() {
|
||||
return suggest(null);
|
||||
}
|
||||
|
@ -46,7 +49,7 @@ public abstract class AbstractZigToolchain {
|
|||
}
|
||||
|
||||
public ZigCompilerTool zig() {
|
||||
return new ZigCompilerTool(this);
|
||||
return zig.get();
|
||||
}
|
||||
|
||||
public abstract int executionTimeoutInMilliseconds();
|
||||
|
|
|
@ -18,17 +18,23 @@ package com.falsepattern.zigbrains.project.toolchain;
|
|||
|
||||
import com.intellij.execution.wsl.WslPath;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class LocalZigToolchainProvider implements ZigToolchainProvider{
|
||||
public class LocalZigToolchainProvider implements ZigToolchainProvider {
|
||||
private static final Map<Path, LocalZigToolchain> tcCache = ContainerUtil.createWeakKeyWeakValueMap();
|
||||
@Override
|
||||
public @Nullable AbstractZigToolchain getToolchain(Path homePath) {
|
||||
if (SystemInfo.isWindows && WslPath.isWslUncPath(homePath.toString())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new LocalZigToolchain(homePath);
|
||||
return tcCache.computeIfAbsent(homePath, LocalZigToolchain::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.toolchain.stdlib;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.AdditionalLibraryRootsProvider;
|
||||
import com.intellij.openapi.roots.SyntheticLibrary;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class ZigLibraryRootProvider extends AdditionalLibraryRootsProvider {
|
||||
@Override
|
||||
public @NotNull Collection<SyntheticLibrary> getAdditionalProjectLibraries(@NotNull Project project) {
|
||||
return Collections.singleton(new ZigSyntheticLibrary(project));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.toolchain.stdlib;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.ApplicationUtil;
|
||||
import com.falsepattern.zigbrains.common.util.PathUtil;
|
||||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||
import com.falsepattern.zigbrains.zig.Icons;
|
||||
import com.falsepattern.zigbrains.zig.parser.ZigFile;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtil;
|
||||
import com.intellij.openapi.roots.SyntheticLibrary;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ZigSyntheticLibrary extends SyntheticLibrary implements ItemPresentation {
|
||||
private final Future<Collection<VirtualFile>> roots;
|
||||
private final Future<String> name;
|
||||
public ZigSyntheticLibrary(Project project) {
|
||||
val service = ZigProjectSettingsService.getInstance(project);
|
||||
val state = service.getState();
|
||||
this.roots = ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||
var roots = pathToVFS(state.getExplicitPathToStd());
|
||||
if (roots != null) {
|
||||
return roots;
|
||||
}
|
||||
val toolchain = state.getToolchain();
|
||||
if (toolchain != null) {
|
||||
val stdPath =
|
||||
toolchain.zig().getStdPath().orElse(null);
|
||||
return pathToVFS(stdPath);
|
||||
}
|
||||
return Collections.emptySet();
|
||||
});
|
||||
|
||||
this.name = ApplicationManager.getApplication()
|
||||
.executeOnPooledThread(() -> Optional.ofNullable(state.getToolchain())
|
||||
.flatMap(tc -> tc.zig().queryVersion())
|
||||
.map(version -> "Zig " + version)
|
||||
.orElse("Zig"));
|
||||
}
|
||||
|
||||
private static @Nullable Collection<VirtualFile> pathToVFS(String path) {
|
||||
if (path != null && !path.isEmpty()) {
|
||||
val thePath = PathUtil.pathFromString(path);
|
||||
if (thePath != null) {
|
||||
val file = VfsUtil.findFile(thePath, true);
|
||||
if (file != null) {
|
||||
val children = file.getChildren();
|
||||
if (children != null && children.length > 0)
|
||||
return Arrays.asList(children);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public @NotNull Collection<VirtualFile> getSourceRoots() {
|
||||
try {
|
||||
return roots.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<VirtualFile> getBinaryRoots() {
|
||||
return super.getBinaryRoots();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof ZigSyntheticLibrary other && Objects.equals(roots.get(), other.roots.get());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(roots.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NlsSafe @Nullable String getPresentableText() {
|
||||
try {
|
||||
return name.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
return "Zig";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Icon getIcon(boolean unused) {
|
||||
return Icons.ZIG;
|
||||
}
|
||||
}
|
|
@ -16,20 +16,45 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.toolchain.tools;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.Lazy;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainEnvironmentSerializable;
|
||||
import com.google.gson.Gson;
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
public class ZigCompilerTool extends AbstractZigTool{
|
||||
public static final String TOOL_NAME = "zig";
|
||||
private final Lazy<Optional<String>> version;
|
||||
private final Lazy<Optional<String>> stdPath;
|
||||
|
||||
public ZigCompilerTool(AbstractZigToolchain toolchain) {
|
||||
super(toolchain, TOOL_NAME);
|
||||
val app = ApplicationManager.getApplication();
|
||||
val baseFuture = app.executeOnPooledThread(() -> getEnv(null));
|
||||
version = new Lazy<>(() -> {
|
||||
try {
|
||||
return baseFuture.get().map(ZigToolchainEnvironmentSerializable::version);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
stdPath = new Lazy<>(() -> {
|
||||
try {
|
||||
return baseFuture.get().map(ZigToolchainEnvironmentSerializable::stdDirectory);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<ZigToolchainEnvironmentSerializable> getEnv(@Nullable Path workingDirectory) {
|
||||
|
@ -39,11 +64,11 @@ public class ZigCompilerTool extends AbstractZigTool{
|
|||
|
||||
}
|
||||
|
||||
public Optional<String> getStdPath(@Nullable Path workingDirectory) {
|
||||
return getEnv(workingDirectory).map(ZigToolchainEnvironmentSerializable::stdDirectory);
|
||||
public Optional<String> getStdPath() {
|
||||
return stdPath.get();
|
||||
}
|
||||
|
||||
public Optional<String> queryVersion(@Nullable Path workingDirectory) {
|
||||
return getEnv(workingDirectory).map(ZigToolchainEnvironmentSerializable::version);
|
||||
public Optional<String> queryVersion() {
|
||||
return version.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
<consoleFilterProvider implementation="com.falsepattern.zigbrains.project.console.ZigConsoleFilterProvider"/>
|
||||
<analyzeStacktraceFilter implementation="com.falsepattern.zigbrains.project.console.ZigSourceFileFilter"/>
|
||||
|
||||
<additionalLibraryRootsProvider implementation="com.falsepattern.zigbrains.project.toolchain.stdlib.ZigLibraryRootProvider"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.falsepattern.zigbrains">
|
||||
|
|
Loading…
Add table
Reference in a new issue