feat!!: Overhauled configs and project creation
This commit is contained in:
parent
125b97fb3b
commit
1f042fad34
43 changed files with 1059 additions and 861 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -18,12 +18,22 @@ Changelog structure reference:
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Completely overhauled the configuration system and the new project creation window. All the configs have been unified
|
||||||
|
into a single screen, and project creation has been fully integrated as a mainline feature, instead of just a "nice to have".
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- LSP
|
- LSP
|
||||||
- The injection of the various language actions (Go to declaration/implementation, reformat, etc.) has been
|
- The injection of the various language actions (Go to declaration/implementation, reformat, etc.) has been
|
||||||
reimplemented from the ground up to be much more reliable and compatible in the presence of other languages and plugins.
|
reimplemented from the ground up to be much more reliable and compatible in the presence of other languages and plugins.
|
||||||
|
|
||||||
|
- Zig, ZLS
|
||||||
|
- The configurations have been unified into a single cohesive interface
|
||||||
|
- Improved auto-detection for both Zig and ZLS
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Project
|
- Project
|
||||||
|
|
65
README.md
65
README.md
|
@ -54,24 +54,15 @@ and might as well utilize the full semver string for extra information.
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
<!-- Plugin description -->
|
<!-- Plugin description -->
|
||||||
A multifunctional Zig Programming Language plugin for the IDEA platform.
|
Adds support for the Zig Language, utilizing the ZLS language server for advanced coding assistance.
|
||||||
|
|
||||||
Core features:
|
## Quick setup guide for Zig and ZLS
|
||||||
- Uses ZLS (Zig Language Server) for code assistance, syntax highlighting, and anything to do with coding assistance
|
|
||||||
- Supports build.zig.zon files with autocomplete
|
|
||||||
- Per-project Zig toolchain integration
|
|
||||||
- Debugging support for CLion (builtin), and IDEA Ultimate [With this plugin](https://plugins.jetbrains.com/plugin/12775-native-debugging-support)
|
|
||||||
- Gutter icon for running main(), tests, and build
|
|
||||||
|
|
||||||
|
1. Download the latest version of Zig from https://ziglang.org/download
|
||||||
## Setting up the language server
|
2. Download and compile the ZLS language server, available at https://github.com/zigtools/zls
|
||||||
|
3. Go to `Settings` -> `Languages & Frameworks` -> `Zig`, and point the `Toolchain Location` and `ZLS path` to the correct places
|
||||||
If you have `zls` available on PATH, ZigBrains will automatically discover it. If not, follow this guide:
|
4. Open a .zig file, and wait for the circle in the bottom status bar to turn Green (empty).
|
||||||
|
See below (`LSP status icon explanation`) for an explanation on what the circle means.
|
||||||
1. Download or compile the ZLS language server, available at https://github.com/zigtools/zls
|
|
||||||
2. Go to `Settings` -> `Languages & Frameworks` -> `ZLS` -> `ZLS path` -> set the path to the `zls` executable you downloaded or compiled
|
|
||||||
3. Open a .zig file, and wait for the circle in the bottom status bar to turn Green (empty).
|
|
||||||
See below for an explanation on what the circle means.
|
|
||||||
|
|
||||||
### LSP status icon explanation
|
### LSP status icon explanation
|
||||||
Red (X symbol):
|
Red (X symbol):
|
||||||
|
@ -85,6 +76,13 @@ LSP server is running.
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
|
|
||||||
|
### Note
|
||||||
|
Debugging on Linux/MacOS/Unix is only available in CLion, as ZigBrains depends on the C++ toolchains system.
|
||||||
|
|
||||||
|
On Windows, debugging is also available with the help of the
|
||||||
|
[Native Debugging Support](https://plugins.jetbrains.com/plugin/12775-native-debugging-support), which is unfortunately
|
||||||
|
only compatible with paid IDEs.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
Due to technical limitations, the C++ toolchains cannot be used for debugging zig code on windows.
|
Due to technical limitations, the C++ toolchains cannot be used for debugging zig code on windows.
|
||||||
|
@ -106,39 +104,4 @@ Note: There is a small issue with the LLDB debugger which does not happen with G
|
||||||
instruction (usually, deep inside the zig standard library's startup code). Unfortunately, we have not found a fix for
|
instruction (usually, deep inside the zig standard library's startup code). Unfortunately, we have not found a fix for
|
||||||
this yet, but fortunately it doesn't break anything, just a bit of inconvenience.
|
this yet, but fortunately it doesn't break anything, just a bit of inconvenience.
|
||||||
|
|
||||||
## Feature tracker:
|
|
||||||
|
|
||||||
### .zig files:
|
|
||||||
- Code completion
|
|
||||||
- Code folding
|
|
||||||
- Code formatting
|
|
||||||
- Syntax highlighting
|
|
||||||
- Inlay hints
|
|
||||||
- Basic error diagnostics
|
|
||||||
- Go to definition
|
|
||||||
- Rename symbol
|
|
||||||
- Hover documentation
|
|
||||||
- Go to implementations / find usages
|
|
||||||
- Brace/Parenthesis/Bracket matching
|
|
||||||
- Debugging (CLion/CLion Nova)
|
|
||||||
- File creation prompt
|
|
||||||
- Gutter launch buttons
|
|
||||||
- Commenter (thanks @MarioAriasC !)
|
|
||||||
|
|
||||||
- TODO:
|
|
||||||
- Workspace Symbols
|
|
||||||
|
|
||||||
### .zon files:
|
|
||||||
- Syntax highlighting
|
|
||||||
- Formatting and indentation
|
|
||||||
- Code completion
|
|
||||||
- Brace folding
|
|
||||||
- Automatic brace and quote pairing
|
|
||||||
|
|
||||||
### Toolchain:
|
|
||||||
- Basic per-project toolchain management
|
|
||||||
- Run configurations
|
|
||||||
- Debugging (CLion/IDEA Ultimate)
|
|
||||||
- Project generation (thanks @JensvandeWiel !)
|
|
||||||
|
|
||||||
<!-- Plugin description end -->
|
<!-- Plugin description end -->
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.intellij.openapi.options.Configurable;
|
||||||
|
import com.intellij.openapi.options.ConfigurationException;
|
||||||
|
import com.intellij.ui.JBColor;
|
||||||
|
import lombok.val;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static com.falsepattern.zigbrains.common.util.dsl.JavaPanel.newPanel;
|
||||||
|
|
||||||
|
public abstract class MultiConfigurable implements Configurable {
|
||||||
|
private final SubConfigurable[] configurables;
|
||||||
|
protected MultiConfigurable(SubConfigurable... configurables) {
|
||||||
|
this.configurables = Arrays.copyOf(configurables, configurables.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable JComponent createComponent() {
|
||||||
|
return newPanel(p -> {
|
||||||
|
for (val configurable: configurables) {
|
||||||
|
configurable.createComponent(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isModified() {
|
||||||
|
for (val configurable: configurables) {
|
||||||
|
if (configurable.isModified())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply() throws ConfigurationException {
|
||||||
|
for (val config: configurables) {
|
||||||
|
config.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
for (val config: configurables) {
|
||||||
|
config.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disposeUIResources() {
|
||||||
|
for (val config: configurables) {
|
||||||
|
config.disposeUIResources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.dsl.JavaPanel;
|
||||||
|
import com.intellij.openapi.options.ConfigurationException;
|
||||||
|
|
||||||
|
public interface SubConfigurable {
|
||||||
|
void createComponent(JavaPanel panel);
|
||||||
|
boolean isModified();
|
||||||
|
void apply() throws ConfigurationException;
|
||||||
|
void reset();
|
||||||
|
void disposeUIResources();
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.PersistentStateComponent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class WrappingStateComponent<T> implements PersistentStateComponent<T> {
|
||||||
|
private T state;
|
||||||
|
public WrappingStateComponent(@NotNull T initialState) {
|
||||||
|
this.state = initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull T getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadState(@NotNull T state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
package com.falsepattern.zigbrains.common.util;
|
package com.falsepattern.zigbrains.common.util;
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
|
import com.intellij.openapi.util.SystemInfo;
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -24,7 +25,9 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class FileUtil {
|
public class FileUtil {
|
||||||
private static final Logger LOG = Logger.getInstance(FileUtil.class);
|
private static final Logger LOG = Logger.getInstance(FileUtil.class);
|
||||||
|
@ -96,6 +99,10 @@ public class FileUtil {
|
||||||
return LocalFileSystem.getInstance().findFileByIoFile(new File(uri));
|
return LocalFileSystem.getInstance().findFileByIoFile(new File(uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static VirtualFile virtualFileFromPath(Path path) {
|
||||||
|
return LocalFileSystem.getInstance().findFileByNioFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms an URI string into a VFS file
|
* Transforms an URI string into a VFS file
|
||||||
*
|
*
|
||||||
|
@ -125,6 +132,28 @@ public class FileUtil {
|
||||||
return path != null ? sanitizeURI(path.toUri().toString()) : null;
|
return path != null ? sanitizeURI(path.toUri().toString()) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Optional<Path> findExecutableOnPATH(String exe) {
|
||||||
|
var exeName = SystemInfo.isWindows ? exe + ".exe" : exe;
|
||||||
|
var PATH = System.getenv("PATH").split(File.pathSeparator);
|
||||||
|
for (var dir: PATH) {
|
||||||
|
var path = Path.of(dir);
|
||||||
|
try {
|
||||||
|
path = path.toAbsolutePath();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!Files.exists(path) || !Files.isDirectory(path)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var exePath = path.resolve(exeName).toAbsolutePath();
|
||||||
|
if (!Files.isRegularFile(exePath) || !Files.isExecutable(exePath)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return Optional.of(exePath);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object representing the OS type (Windows or Unix)
|
* Object representing the OS type (Windows or Unix)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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 kotlin.Unit;
|
||||||
|
import kotlin.jvm.functions.Function1;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class KtUtil {
|
||||||
|
public static <T> Function1<T, Unit> $f(Consumer<T> f) {
|
||||||
|
return (x) -> {
|
||||||
|
f.accept(x);
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,8 +17,11 @@
|
||||||
package com.falsepattern.zigbrains.common.util;
|
package com.falsepattern.zigbrains.common.util;
|
||||||
|
|
||||||
import com.intellij.openapi.util.SystemInfo;
|
import com.intellij.openapi.util.SystemInfo;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public class PathUtil {
|
public class PathUtil {
|
||||||
|
@ -30,4 +33,22 @@ public class PathUtil {
|
||||||
var exeName = SystemInfo.isWindows ? toolName + ".exe" : toolName;
|
var exeName = SystemInfo.isWindows ? toolName + ".exe" : toolName;
|
||||||
return path.resolve(exeName).toAbsolutePath();
|
return path.resolve(exeName).toAbsolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @Nullable Path pathFromString(@Nullable String pathString) {
|
||||||
|
if (pathString == null || pathString.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Path.of(pathString);
|
||||||
|
} catch (InvalidPathException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull String stringFromPath(@Nullable Path path) {
|
||||||
|
if (path == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return path.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import com.intellij.openapi.ui.TextComponentAccessor;
|
||||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||||
import com.intellij.openapi.util.NlsContexts;
|
import com.intellij.openapi.util.NlsContexts;
|
||||||
import com.intellij.ui.DocumentAdapter;
|
import com.intellij.ui.DocumentAdapter;
|
||||||
|
import com.intellij.ui.components.fields.ExtendableTextField;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ public class TextFieldUtil {
|
||||||
Disposable disposable,
|
Disposable disposable,
|
||||||
@NlsContexts.DialogTitle String dialogTitle,
|
@NlsContexts.DialogTitle String dialogTitle,
|
||||||
Runnable onTextChanged) {
|
Runnable onTextChanged) {
|
||||||
val component = new TextFieldWithBrowseButton(null, disposable);
|
val component = new TextFieldWithBrowseButton(new ExtendableTextField(), null, disposable);
|
||||||
component.addBrowseFolderListener(dialogTitle, null, null, fileChooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
|
component.addBrowseFolderListener(dialogTitle, null, null, fileChooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
|
||||||
addTextChangeListener(component.getChildComponent(), ignored -> onTextChanged.run());
|
addTextChangeListener(component.getChildComponent(), ignored -> onTextChanged.run());
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* 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.dsl;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.KtUtil;
|
||||||
|
import com.intellij.openapi.ui.DialogPanel;
|
||||||
|
import com.intellij.ui.components.JBLabel;
|
||||||
|
import com.intellij.ui.dsl.builder.Align;
|
||||||
|
import com.intellij.ui.dsl.builder.AlignX;
|
||||||
|
import com.intellij.ui.dsl.builder.BuilderKt;
|
||||||
|
import com.intellij.ui.dsl.builder.Panel;
|
||||||
|
import com.intellij.ui.dsl.builder.RightGap;
|
||||||
|
import com.intellij.ui.dsl.builder.Row;
|
||||||
|
import com.intellij.ui.dsl.builder.RowsRange;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import static com.falsepattern.zigbrains.common.util.KtUtil.$f;
|
||||||
|
|
||||||
|
public class JavaPanel {
|
||||||
|
private final Panel panel;
|
||||||
|
|
||||||
|
public JavaPanel(Panel p) {
|
||||||
|
this.panel = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cell(String label, JComponent component, Align align) {
|
||||||
|
row(label, row -> row.cell(component).align(align));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cell(String label, JComponent component) {
|
||||||
|
row(label, row -> row.cell(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cell(JComponent component) {
|
||||||
|
cell("", component);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void label(String label) {
|
||||||
|
panel.row((JLabel) null, $f(r -> r.label(label)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void gap() {
|
||||||
|
panel.gap(RightGap.SMALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void row(Consumer<Row> row) {
|
||||||
|
panel.row((JLabel) null, (r) -> {
|
||||||
|
row.accept(r);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void row(String text, Consumer<Row> row) {
|
||||||
|
panel.row(text, $f(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void separator() {
|
||||||
|
panel.separator(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void separator(Color color) {
|
||||||
|
panel.separator(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void panel(Consumer<JavaPanel> c) {
|
||||||
|
panel.panel($f(p -> {
|
||||||
|
c.accept(new JavaPanel(p));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DialogPanel newPanel(Consumer<JavaPanel> c) {
|
||||||
|
return BuilderKt.panel((p) -> {
|
||||||
|
c.accept(new JavaPanel(p));
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void group(String title, Consumer<JavaPanel> c) {
|
||||||
|
panel.groupRowsRange(title, false, null, null, (p) -> {
|
||||||
|
c.accept(new JavaPanel(p));
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.ide.config;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.MultiConfigurable;
|
||||||
|
import com.falsepattern.zigbrains.project.ide.project.ZigProjectConfigurable;
|
||||||
|
import com.falsepattern.zigbrains.zig.settings.ZLSSettingsConfigurable;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.NlsContexts;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ZigConfigurable extends MultiConfigurable {
|
||||||
|
public ZigConfigurable(@NotNull Project project) {
|
||||||
|
super(new ZigProjectConfigurable(project), new ZLSSettingsConfigurable(project));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public @NlsContexts.ConfigurableName String getDisplayName() {
|
||||||
|
return "Zig";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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.ide.newproject;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectConfigurationData;
|
||||||
|
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectGeneratorPeer;
|
||||||
|
import com.falsepattern.zigbrains.project.ide.project.ZigDefaultTemplate;
|
||||||
|
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectSettingsStep;
|
||||||
|
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||||
|
import com.falsepattern.zigbrains.zig.Icons;
|
||||||
|
import com.falsepattern.zigbrains.zig.settings.ZLSProjectSettingsService;
|
||||||
|
import com.intellij.facet.ui.ValidationResult;
|
||||||
|
import com.intellij.ide.util.projectWizard.AbstractNewProjectStep;
|
||||||
|
import com.intellij.ide.util.projectWizard.CustomStepProjectGenerator;
|
||||||
|
import com.intellij.notification.Notification;
|
||||||
|
import com.intellij.notification.NotificationType;
|
||||||
|
import com.intellij.notification.Notifications;
|
||||||
|
import com.intellij.openapi.application.WriteAction;
|
||||||
|
import com.intellij.openapi.module.Module;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.NlsContexts;
|
||||||
|
import com.intellij.openapi.vfs.VfsUtil;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.openapi.wm.impl.welcomeScreen.AbstractActionWithPanel;
|
||||||
|
import com.intellij.platform.DirectoryProjectGenerator;
|
||||||
|
import com.intellij.platform.ProjectGeneratorPeer;
|
||||||
|
import com.intellij.util.ResourceUtil;
|
||||||
|
import lombok.val;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class ZigDirectoryProjectGenerator implements DirectoryProjectGenerator<ZigProjectConfigurationData>,
|
||||||
|
CustomStepProjectGenerator<ZigProjectConfigurationData> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @NlsContexts.Label String getName() {
|
||||||
|
return "Zig";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Icon getLogo() {
|
||||||
|
return Icons.ZIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ProjectGeneratorPeer<ZigProjectConfigurationData> createPeer() {
|
||||||
|
return new ZigProjectGeneratorPeer(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ValidationResult validate(@NotNull String baseDirPath) {
|
||||||
|
return ValidationResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateProject(@NotNull Project project, @NotNull VirtualFile baseDir, @NotNull ZigProjectConfigurationData data, @NotNull Module module) {
|
||||||
|
data.generateProject(this, project, baseDir, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractActionWithPanel createStep(DirectoryProjectGenerator<ZigProjectConfigurationData> projectGenerator, AbstractNewProjectStep.AbstractCallback<ZigProjectConfigurationData> callback) {
|
||||||
|
return new ZigProjectSettingsStep(projectGenerator);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,23 +14,28 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.ide.util.projectwizard;
|
package com.falsepattern.zigbrains.project.ide.newproject;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectConfigurationData;
|
|
||||||
import com.falsepattern.zigbrains.project.openapi.module.ZigModuleType;
|
import com.falsepattern.zigbrains.project.openapi.module.ZigModuleType;
|
||||||
|
import com.falsepattern.zigbrains.project.util.ExperimentUtil;
|
||||||
import com.intellij.ide.util.projectWizard.ModuleBuilder;
|
import com.intellij.ide.util.projectWizard.ModuleBuilder;
|
||||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
||||||
import com.intellij.ide.util.projectWizard.WizardContext;
|
import com.intellij.ide.util.projectWizard.WizardContext;
|
||||||
|
import com.intellij.ide.wizard.CommitStepException;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
import com.intellij.openapi.module.ModuleType;
|
import com.intellij.openapi.module.ModuleType;
|
||||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||||
import com.intellij.openapi.util.Disposer;
|
import com.intellij.openapi.util.Disposer;
|
||||||
|
import com.intellij.util.ui.JBUI;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
public class ZigModuleBuilder extends ModuleBuilder {
|
public class ZigModuleBuilder extends ModuleBuilder {
|
||||||
public @Nullable ZigProjectConfigurationData configurationData = null;
|
public @Nullable ZigProjectConfigurationData configurationData = null;
|
||||||
|
public boolean forceGitignore = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModuleType<?> getModuleType() {
|
public ModuleType<?> getModuleType() {
|
||||||
|
@ -39,7 +44,7 @@ public class ZigModuleBuilder extends ModuleBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupRootModel(@NotNull ModifiableRootModel modifiableRootModel) {
|
public void setupRootModel(@NotNull ModifiableRootModel modifiableRootModel) {
|
||||||
createProject(modifiableRootModel, "git");
|
createProject(modifiableRootModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,8 +54,8 @@ public class ZigModuleBuilder extends ModuleBuilder {
|
||||||
return step;
|
return step;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createProject(ModifiableRootModel modifiableRootModel, @Nullable String vcs) {
|
public void createProject(ModifiableRootModel rootModel) {
|
||||||
val contentEntry = doAddContentEntry(modifiableRootModel);
|
val contentEntry = doAddContentEntry(rootModel);
|
||||||
if (contentEntry == null) {
|
if (contentEntry == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +63,36 @@ public class ZigModuleBuilder extends ModuleBuilder {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modifiableRootModel.inheritSdk();
|
if (configurationData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
configurationData.generateProject(this, rootModel.getProject(), root, forceGitignore);
|
||||||
root.refresh(false, true);
|
root.refresh(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ZigModuleWizardStep extends ModuleWizardStep {
|
||||||
|
private final ZigProjectGeneratorPeer peer = new ZigProjectGeneratorPeer(true);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JComponent getComponent() {
|
||||||
|
return withBorderIfNeeded(peer.getComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disposeUIResources() {
|
||||||
|
peer.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDataModel() {
|
||||||
|
ZigModuleBuilder.this.configurationData = peer.getSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends JComponent> T withBorderIfNeeded(T component) {
|
||||||
|
if (ExperimentUtil.isNewWizard()) {
|
||||||
|
component.setBorder(JBUI.Borders.empty(14, 20));
|
||||||
|
}
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -16,19 +16,23 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.ide.newproject;
|
package com.falsepattern.zigbrains.project.ide.newproject;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.dsl.JavaPanel;
|
||||||
import com.falsepattern.zigbrains.project.ide.project.ZigDefaultTemplate;
|
import com.falsepattern.zigbrains.project.ide.project.ZigDefaultTemplate;
|
||||||
import com.falsepattern.zigbrains.project.ide.project.ZigProjectSettingsPanel;
|
import com.falsepattern.zigbrains.project.ide.project.ZigProjectSettingsPanel;
|
||||||
import com.falsepattern.zigbrains.project.ide.project.ZigProjectTemplate;
|
import com.falsepattern.zigbrains.project.ide.project.ZigProjectTemplate;
|
||||||
|
import com.falsepattern.zigbrains.zig.settings.ZLSSettingsPanel;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
import com.intellij.openapi.actionSystem.ActionToolbarPosition;
|
import com.intellij.openapi.actionSystem.ActionToolbarPosition;
|
||||||
import com.intellij.openapi.util.Disposer;
|
|
||||||
import com.intellij.ui.ColoredListCellRenderer;
|
import com.intellij.ui.ColoredListCellRenderer;
|
||||||
|
import com.intellij.ui.JBColor;
|
||||||
import com.intellij.ui.ToolbarDecorator;
|
import com.intellij.ui.ToolbarDecorator;
|
||||||
|
import com.intellij.ui.components.JBCheckBox;
|
||||||
import com.intellij.ui.components.JBList;
|
import com.intellij.ui.components.JBList;
|
||||||
import com.intellij.ui.dsl.builder.AlignX;
|
import com.intellij.ui.dsl.builder.AlignX;
|
||||||
import com.intellij.ui.dsl.builder.AlignY;
|
import com.intellij.ui.dsl.builder.AlignY;
|
||||||
import com.intellij.ui.dsl.builder.Panel;
|
import com.intellij.ui.dsl.builder.Panel;
|
||||||
import com.intellij.util.ui.JBUI;
|
import com.intellij.util.ui.JBUI;
|
||||||
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
|
@ -40,11 +44,20 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class ZigNewProjectPanel implements Disposable {
|
public class ZigNewProjectPanel implements Disposable {
|
||||||
private final ZigProjectSettingsPanel projectSettingsPanel = new ZigProjectSettingsPanel();
|
private boolean handleGit;
|
||||||
|
private JBCheckBox git = new JBCheckBox();
|
||||||
|
private ZigProjectSettingsPanel projConf;
|
||||||
|
private ZLSSettingsPanel zlsConf;
|
||||||
|
|
||||||
|
public ZigNewProjectPanel(boolean handleGit) {
|
||||||
|
this.handleGit = handleGit;
|
||||||
|
projConf = new ZigProjectSettingsPanel();
|
||||||
|
zlsConf = new ZLSSettingsPanel();
|
||||||
|
}
|
||||||
|
|
||||||
public ZigProjectConfigurationData getData() {
|
public ZigProjectConfigurationData getData() {
|
||||||
ZigProjectTemplate selectedTemplate = templateList.getSelectedValue();
|
ZigProjectTemplate selectedTemplate = templateList.getSelectedValue();
|
||||||
return new ZigProjectConfigurationData(projectSettingsPanel.getData(), selectedTemplate);
|
return new ZigProjectConfigurationData(handleGit && git.isSelected(), projConf.getData(), zlsConf.getData(), selectedTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<ZigProjectTemplate> defaultTemplates = Arrays.asList(
|
private final List<ZigProjectTemplate> defaultTemplates = Arrays.asList(
|
||||||
|
@ -75,23 +88,27 @@ public class ZigNewProjectPanel implements Disposable {
|
||||||
.disableAddAction()
|
.disableAddAction()
|
||||||
.disableRemoveAction();
|
.disableRemoveAction();
|
||||||
|
|
||||||
public void attachPanelTo(Panel panel) {
|
public void attachPanelTo(JavaPanel p) {
|
||||||
projectSettingsPanel.attachPanelTo(panel);
|
if (handleGit) {
|
||||||
|
p.row("Create Git repository", r -> r.cell(git));
|
||||||
panel.groupRowsRange("Zig Project Template", false, null, null, (p) -> {
|
}
|
||||||
p.row((JLabel) null, (r) -> {
|
p.group("Zig Project Template", (p2) -> {
|
||||||
|
p2.row((r) -> {
|
||||||
r.resizableRow();
|
r.resizableRow();
|
||||||
r.cell(templateToolbar.createPanel())
|
r.cell(templateToolbar.createPanel())
|
||||||
.align(AlignX.FILL)
|
.align(AlignX.FILL)
|
||||||
.align(AlignY.FILL);
|
.align(AlignY.FILL);
|
||||||
return null;
|
|
||||||
});
|
});
|
||||||
return null;
|
|
||||||
});
|
});
|
||||||
|
projConf.attachPanelTo(p);
|
||||||
|
zlsConf.attachPanelTo(p);
|
||||||
|
projConf.autodetect();
|
||||||
|
zlsConf.autodetect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
Disposer.dispose(projectSettingsPanel);
|
projConf = null;
|
||||||
|
zlsConf = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,14 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.ide.newproject;
|
package com.falsepattern.zigbrains.project.ide.newproject;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.common.util.ApplicationUtil;
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.project.ide.util.projectwizard.ZigModuleBuilder;
|
|
||||||
import com.falsepattern.zigbrains.project.platform.ZigProjectGeneratorPeer;
|
|
||||||
import com.falsepattern.zigbrains.zig.Icons;
|
import com.falsepattern.zigbrains.zig.Icons;
|
||||||
import com.intellij.ide.wizard.AbstractNewProjectWizardStep;
|
import com.intellij.ide.wizard.AbstractNewProjectWizardStep;
|
||||||
import com.intellij.ide.wizard.GitNewProjectWizardData;
|
import com.intellij.ide.wizard.GitNewProjectWizardData;
|
||||||
import com.intellij.ide.wizard.NewProjectWizardStep;
|
import com.intellij.ide.wizard.NewProjectWizardStep;
|
||||||
import com.intellij.ide.wizard.language.LanguageGeneratorNewProjectWizard;
|
import com.intellij.ide.wizard.language.LanguageGeneratorNewProjectWizard;
|
||||||
import com.intellij.openapi.module.Module;
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||||
import com.intellij.openapi.vfs.VfsUtil;
|
|
||||||
import com.intellij.ui.dsl.builder.AlignX;
|
import com.intellij.ui.dsl.builder.AlignX;
|
||||||
import com.intellij.ui.dsl.builder.Panel;
|
import com.intellij.ui.dsl.builder.Panel;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
@ -35,8 +31,6 @@ import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public class ZigNewProjectWizard implements LanguageGeneratorNewProjectWizard {
|
public class ZigNewProjectWizard implements LanguageGeneratorNewProjectWizard {
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@ -63,7 +57,7 @@ public class ZigNewProjectWizard implements LanguageGeneratorNewProjectWizard {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ZigNewProjectWizardStep extends AbstractNewProjectWizardStep {
|
private static class ZigNewProjectWizardStep extends AbstractNewProjectWizardStep {
|
||||||
private final ZigProjectGeneratorPeer peer = new ZigProjectGeneratorPeer();
|
private final ZigProjectGeneratorPeer peer = new ZigProjectGeneratorPeer(false);
|
||||||
|
|
||||||
public ZigNewProjectWizardStep(@NotNull NewProjectWizardStep parentStep) {
|
public ZigNewProjectWizardStep(@NotNull NewProjectWizardStep parentStep) {
|
||||||
super(parentStep);
|
super(parentStep);
|
||||||
|
@ -81,41 +75,10 @@ public class ZigNewProjectWizard implements LanguageGeneratorNewProjectWizard {
|
||||||
@Override
|
@Override
|
||||||
public void setupProject(@NotNull Project project) {
|
public void setupProject(@NotNull Project project) {
|
||||||
val builder = new ZigModuleBuilder();
|
val builder = new ZigModuleBuilder();
|
||||||
val modList = builder.commit(project);
|
|
||||||
if (modList == null || modList.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
val module = modList.get(0);
|
|
||||||
|
|
||||||
ModuleRootModificationUtil.updateModel(module, rootModel -> {
|
|
||||||
builder.configurationData = peer.getSettings();
|
builder.configurationData = peer.getSettings();
|
||||||
builder.createProject(rootModel, "none");
|
|
||||||
var gitData = GitNewProjectWizardData.Companion.getGitData(this);
|
var gitData = GitNewProjectWizardData.Companion.getGitData(this);
|
||||||
if (gitData == null) {
|
builder.forceGitignore = gitData != null && gitData.getGit();
|
||||||
return;
|
builder.commit(project);
|
||||||
}
|
|
||||||
if (gitData.getGit()) {
|
|
||||||
ApplicationUtil.writeAction(() -> createGitIgnoreFile(getContext().getProjectDirectory(), module));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String GITIGNORE = ".gitignore";
|
|
||||||
|
|
||||||
private static void createGitIgnoreFile(Path projectDir, Module module) {
|
|
||||||
try {
|
|
||||||
val directory = VfsUtil.createDirectoryIfMissing(projectDir.toString());
|
|
||||||
if (directory == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
val existingFile = directory.findChild(GITIGNORE);
|
|
||||||
if (existingFile != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
directory.createChildData(module, GITIGNORE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,132 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.ide.newproject;
|
package com.falsepattern.zigbrains.project.ide.newproject;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.ide.project.ZigProjectSettingsPanel;
|
import com.falsepattern.zigbrains.common.util.ApplicationUtil;
|
||||||
|
import com.falsepattern.zigbrains.project.ide.project.ZigDefaultTemplate;
|
||||||
import com.falsepattern.zigbrains.project.ide.project.ZigProjectTemplate;
|
import com.falsepattern.zigbrains.project.ide.project.ZigProjectTemplate;
|
||||||
|
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettings;
|
||||||
|
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||||
|
import com.falsepattern.zigbrains.zig.settings.ZLSProjectSettingsService;
|
||||||
|
import com.falsepattern.zigbrains.zig.settings.ZLSSettings;
|
||||||
|
import com.intellij.ide.wizard.GitNewProjectWizardData;
|
||||||
|
import com.intellij.notification.Notification;
|
||||||
|
import com.intellij.notification.NotificationType;
|
||||||
|
import com.intellij.notification.Notifications;
|
||||||
|
import com.intellij.openapi.GitRepositoryInitializer;
|
||||||
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
|
import com.intellij.openapi.application.WriteAction;
|
||||||
|
import com.intellij.openapi.module.Module;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.vfs.VfsUtil;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.util.ResourceUtil;
|
||||||
|
import lombok.Cleanup;
|
||||||
|
import lombok.val;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public record ZigProjectConfigurationData(ZigProjectSettingsPanel.SettingsData settings, ZigProjectTemplate selectedTemplate) {
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public record ZigProjectConfigurationData(boolean git, ZigProjectSettings projConf, ZLSSettings zlsConf, ZigProjectTemplate selectedTemplate) {
|
||||||
|
|
||||||
|
private static String getResourceString(String path) throws IOException {
|
||||||
|
byte[] data = ResourceUtil.getResourceAsBytes(path, ZigDirectoryProjectGenerator.class.getClassLoader());
|
||||||
|
if (data == null)
|
||||||
|
throw new IOException("Could not find resource " + path + "!");
|
||||||
|
return new String(data, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateProject(@NotNull Object requestor, @NotNull Project project, @NotNull VirtualFile baseDir, boolean forceGitignore) {
|
||||||
|
val svc = ZigProjectSettingsService.getInstance(project);
|
||||||
|
svc.loadState(this.projConf());
|
||||||
|
ZLSProjectSettingsService.getInstance(project).loadState(this.zlsConf());
|
||||||
|
|
||||||
|
val toolchain = svc.getState().getToolchain();
|
||||||
|
|
||||||
|
val template = this.selectedTemplate();
|
||||||
|
|
||||||
|
if (template instanceof ZigDefaultTemplate.ZigInitTemplate) {
|
||||||
|
if (toolchain == null) {
|
||||||
|
Notifications.Bus.notify(new Notification("ZigBrains.Project",
|
||||||
|
"Tried to generate project with zig init, but zig toolchain is invalid!",
|
||||||
|
NotificationType.ERROR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val zig = toolchain.zig();
|
||||||
|
val resultOpt = zig.callWithArgs(baseDir.toNioPath(), 10000, "init");
|
||||||
|
if (resultOpt.isEmpty()) {
|
||||||
|
Notifications.Bus.notify(new Notification("ZigBrains.Project",
|
||||||
|
"Failed to invoke \"zig init\"!",
|
||||||
|
NotificationType.ERROR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val result = resultOpt.get();
|
||||||
|
if (result.getExitCode() != 0) {
|
||||||
|
Notifications.Bus.notify(new Notification("ZigBrains.Project",
|
||||||
|
"\"zig init\" failed with exit code " + result.getExitCode() + "! Check the IDE log files!",
|
||||||
|
NotificationType.ERROR));
|
||||||
|
System.err.println(result.getStderr());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
val projectName = project.getName();
|
||||||
|
WriteAction.run(() -> {
|
||||||
|
for (val fileTemplate : template.fileTemplates().entrySet()) {
|
||||||
|
var fileName = fileTemplate.getKey();
|
||||||
|
VirtualFile parentDir;
|
||||||
|
if (fileName.contains("/")) {
|
||||||
|
val slashIndex = fileName.indexOf('/');
|
||||||
|
parentDir = baseDir.createChildDirectory(requestor, fileName.substring(0, slashIndex));
|
||||||
|
fileName = fileName.substring(slashIndex + 1);
|
||||||
|
} else {
|
||||||
|
parentDir = baseDir;
|
||||||
|
}
|
||||||
|
val templateDir = fileTemplate.getValue();
|
||||||
|
val resourceData = getResourceString("project-gen/" + templateDir + "/" + fileName + ".template").replace("@@PROJECT_NAME@@", projectName);
|
||||||
|
val targetFile = parentDir.createChildData(requestor, fileName);
|
||||||
|
VfsUtil.saveText(targetFile, resourceData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (git) {
|
||||||
|
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||||
|
val initializer = GitRepositoryInitializer.getInstance();
|
||||||
|
if (initializer != null) {
|
||||||
|
initializer.initRepository(project, baseDir);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (git || forceGitignore) {
|
||||||
|
createGitIgnoreFile(baseDir, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final String GITIGNORE = ".gitignore";
|
||||||
|
|
||||||
|
private static void createGitIgnoreFile(VirtualFile projectDir, Object requestor) {
|
||||||
|
val existingFile = projectDir.findChild(GITIGNORE);
|
||||||
|
if (existingFile != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WriteAction.run(() -> {
|
||||||
|
VirtualFile file = null;
|
||||||
|
try {
|
||||||
|
file = projectDir.createChildData(requestor, GITIGNORE);
|
||||||
|
@Cleanup val res = ZigProjectConfigurationData.class.getResourceAsStream("/fileTemplates/internal/gitignore");
|
||||||
|
if (res == null)
|
||||||
|
return;
|
||||||
|
file.setCharset(StandardCharsets.UTF_8);
|
||||||
|
file.setBinaryContent(res.readAllBytes());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,19 +14,22 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.platform;
|
package com.falsepattern.zigbrains.project.ide.newproject;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.ide.newproject.ZigNewProjectPanel;
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectConfigurationData;
|
|
||||||
import com.intellij.platform.GeneratorPeerImpl;
|
import com.intellij.platform.GeneratorPeerImpl;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
import static com.intellij.ui.dsl.builder.BuilderKt.panel;
|
import static com.falsepattern.zigbrains.common.util.dsl.JavaPanel.newPanel;
|
||||||
|
|
||||||
public class ZigProjectGeneratorPeer extends GeneratorPeerImpl<ZigProjectConfigurationData> {
|
public class ZigProjectGeneratorPeer extends GeneratorPeerImpl<ZigProjectConfigurationData> {
|
||||||
private final ZigNewProjectPanel newProjectPanel = new ZigNewProjectPanel();
|
private final ZigNewProjectPanel newProjectPanel;
|
||||||
|
|
||||||
|
public ZigProjectGeneratorPeer(boolean handleGit) {
|
||||||
|
newProjectPanel = new ZigNewProjectPanel(handleGit);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ZigProjectConfigurationData getSettings() {
|
public @NotNull ZigProjectConfigurationData getSettings() {
|
||||||
|
@ -35,9 +38,10 @@ public class ZigProjectGeneratorPeer extends GeneratorPeerImpl<ZigProjectConfigu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull JComponent getComponent() {
|
public @NotNull JComponent getComponent() {
|
||||||
return panel((p) -> {
|
return newPanel(newProjectPanel::attachPanelTo);
|
||||||
newProjectPanel.attachPanelTo(p);
|
}
|
||||||
return null;
|
|
||||||
});
|
public void dispose() {
|
||||||
|
Disposer.dispose(newProjectPanel);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.ide.util.projectwizard;
|
package com.falsepattern.zigbrains.project.ide.newproject;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectConfigurationData;
|
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectConfigurationData;
|
||||||
import com.intellij.ide.util.projectWizard.AbstractNewProjectStep;
|
import com.intellij.ide.util.projectWizard.AbstractNewProjectStep;
|
|
@ -16,23 +16,17 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.ide.project;
|
package com.falsepattern.zigbrains.project.ide.project;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.SubConfigurable;
|
||||||
|
import com.falsepattern.zigbrains.common.util.dsl.JavaPanel;
|
||||||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||||
import com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity;
|
import com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity;
|
||||||
import com.intellij.openapi.options.Configurable;
|
|
||||||
import com.intellij.openapi.options.ConfigurationException;
|
import com.intellij.openapi.options.ConfigurationException;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.Disposer;
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.openapi.util.NlsContexts;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
public class ZigProjectConfigurable implements SubConfigurable {
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.intellij.ui.dsl.builder.BuilderKt.panel;
|
|
||||||
|
|
||||||
public class ZigProjectConfigurable implements Configurable {
|
|
||||||
private ZigProjectSettingsPanel settingsPanel;
|
private ZigProjectSettingsPanel settingsPanel;
|
||||||
|
|
||||||
private final Project project;
|
private final Project project;
|
||||||
|
@ -42,36 +36,22 @@ public class ZigProjectConfigurable implements Configurable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NlsContexts.ConfigurableName String getDisplayName() {
|
public void createComponent(JavaPanel panel) {
|
||||||
return "Zig";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable JComponent createComponent() {
|
|
||||||
settingsPanel = new ZigProjectSettingsPanel();
|
settingsPanel = new ZigProjectSettingsPanel();
|
||||||
return panel((p) -> {
|
settingsPanel.attachPanelTo(panel);
|
||||||
settingsPanel.attachPanelTo(p);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isModified() {
|
public boolean isModified() {
|
||||||
var zigSettings = ZigProjectSettingsService.getInstance(project);
|
return ZigProjectSettingsService.getInstance(project).isModified(settingsPanel.getData());
|
||||||
var settingsData = settingsPanel.getData();
|
|
||||||
return !Objects.equals(settingsData.toolchain(), zigSettings.getToolchain()) ||
|
|
||||||
!Objects.equals(settingsData.explicitPathToStd(), zigSettings.getExplicitPathToStd());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply() throws ConfigurationException {
|
public void apply() throws ConfigurationException {
|
||||||
val zigSettings = ZigProjectSettingsService.getInstance(project);
|
val service = ZigProjectSettingsService.getInstance(project);
|
||||||
val settingsData = settingsPanel.getData();
|
val data = settingsPanel.getData();
|
||||||
boolean modified = isModified();
|
val modified = service.isModified(data);
|
||||||
zigSettings.modify((settings) -> {
|
service.loadState(data);
|
||||||
settings.setToolchain(settingsData.toolchain());
|
|
||||||
settings.setExplicitPathToStd(settingsData.explicitPathToStd());
|
|
||||||
});
|
|
||||||
if (modified) {
|
if (modified) {
|
||||||
ZLSStartupActivity.initZLS(project);
|
ZLSStartupActivity.initZLS(project);
|
||||||
}
|
}
|
||||||
|
@ -80,10 +60,7 @@ public class ZigProjectConfigurable implements Configurable {
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
val zigSettings = ZigProjectSettingsService.getInstance(project);
|
val zigSettings = ZigProjectSettingsService.getInstance(project);
|
||||||
settingsPanel.setData(new ZigProjectSettingsPanel.SettingsData(
|
settingsPanel.setData(zigSettings.getState());
|
||||||
zigSettings.getExplicitPathToStd(),
|
|
||||||
zigSettings.getToolchain()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,10 +16,13 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.ide.project;
|
package com.falsepattern.zigbrains.project.ide.project;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.PathUtil;
|
||||||
import com.falsepattern.zigbrains.common.util.StringUtil;
|
import com.falsepattern.zigbrains.common.util.StringUtil;
|
||||||
import com.falsepattern.zigbrains.common.util.TextFieldUtil;
|
import com.falsepattern.zigbrains.common.util.TextFieldUtil;
|
||||||
|
import com.falsepattern.zigbrains.common.util.dsl.JavaPanel;
|
||||||
import com.falsepattern.zigbrains.project.openapi.MyDisposable;
|
import com.falsepattern.zigbrains.project.openapi.MyDisposable;
|
||||||
import com.falsepattern.zigbrains.project.openapi.UIDebouncer;
|
import com.falsepattern.zigbrains.project.openapi.UIDebouncer;
|
||||||
|
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettings;
|
||||||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider;
|
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider;
|
||||||
|
@ -29,26 +32,25 @@ import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.ui.JBColor;
|
import com.intellij.ui.JBColor;
|
||||||
import com.intellij.ui.dsl.builder.AlignX;
|
import com.intellij.ui.dsl.builder.AlignX;
|
||||||
import com.intellij.ui.dsl.builder.Panel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static com.falsepattern.zigbrains.common.util.KtUtil.$f;
|
||||||
|
|
||||||
public class ZigProjectSettingsPanel implements MyDisposable {
|
public class ZigProjectSettingsPanel implements MyDisposable {
|
||||||
@Getter
|
@Getter
|
||||||
private boolean disposed = false;
|
private boolean disposed = false;
|
||||||
|
|
||||||
public record SettingsData(@Nullable String explicitPathToStd,
|
|
||||||
@Nullable AbstractZigToolchain toolchain) {}
|
|
||||||
|
|
||||||
private final UIDebouncer versionUpdateDebouncer = new UIDebouncer(this);
|
private final UIDebouncer versionUpdateDebouncer = new UIDebouncer(this);
|
||||||
|
|
||||||
private final ZigToolchainPathChooserComboBox toolchainPathChooserComboBox = new ZigToolchainPathChooserComboBox(this::updateUI);
|
private final TextFieldWithBrowseButton pathToToolchain = TextFieldUtil.pathToDirectoryTextField(this,
|
||||||
|
"Path to the Zig Toolchain",
|
||||||
|
this::updateUI);
|
||||||
|
|
||||||
private final JLabel toolchainVersion = new JLabel();
|
private final JLabel toolchainVersion = new JLabel();
|
||||||
|
|
||||||
|
@ -56,56 +58,57 @@ public class ZigProjectSettingsPanel implements MyDisposable {
|
||||||
"Path to Standard Library",
|
"Path to Standard Library",
|
||||||
() -> {});
|
() -> {});
|
||||||
|
|
||||||
public SettingsData getData() {
|
private void autodetect(ActionEvent e) {
|
||||||
val toolchain = Optional.ofNullable(toolchainPathChooserComboBox.getSelectedPath())
|
autodetect();
|
||||||
.map(ZigToolchainProvider::findToolchain)
|
|
||||||
.orElse(null);
|
|
||||||
return new SettingsData(StringUtil.blankToNull(pathToStdField.getText()), toolchain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(SettingsData value) {
|
public void autodetect() {
|
||||||
toolchainPathChooserComboBox.setSelectedPath(Optional.ofNullable(value.toolchain()).map(tc -> tc.location).orElse(null));
|
val tc = AbstractZigToolchain.suggest();
|
||||||
|
if (tc != null) {
|
||||||
|
pathToToolchain.setText(PathUtil.stringFromPath(tc.getLocation()));
|
||||||
|
updateUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pathToStdField.setText(Optional.ofNullable(value.explicitPathToStd()).orElse(""));
|
public ZigProjectSettings getData() {
|
||||||
|
val toolchain = Optional.of(pathToToolchain.getText())
|
||||||
|
.map(PathUtil::pathFromString)
|
||||||
|
.map(ZigToolchainProvider::findToolchain)
|
||||||
|
.orElse(null);
|
||||||
|
return new ZigProjectSettings(StringUtil.blankToNull(pathToStdField.getText()), toolchain);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(ZigProjectSettings value) {
|
||||||
|
pathToToolchain.setText(Optional.ofNullable(value.getToolchainHomeDirectory())
|
||||||
|
.orElse(""));
|
||||||
|
|
||||||
|
pathToStdField.setText(Optional.ofNullable(value.getExplicitPathToStd()).orElse(""));
|
||||||
|
|
||||||
updateUI();
|
updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachPanelTo(Panel panel) {
|
public void attachPanelTo(JavaPanel p) {
|
||||||
setData(new SettingsData(null,
|
Optional.ofNullable(ZigProjectSettingsService.getInstance(ProjectManager.getInstance().getDefaultProject()))
|
||||||
Optional.ofNullable(ProjectManager.getInstance()
|
.map(ZigProjectSettingsService::getState)
|
||||||
.getDefaultProject()
|
.ifPresent(this::setData);
|
||||||
.getService(ZigProjectSettingsService.class))
|
p.group("Zig Settings", p2 -> {
|
||||||
.map(ZigProjectSettingsService::getToolchain)
|
p2.row("Toolchain location", r -> {
|
||||||
.orElse(AbstractZigToolchain.suggest(Paths.get(".")))));
|
r.cell(pathToToolchain).resizableColumn().align(AlignX.FILL);
|
||||||
|
r.button("Autodetect", $f(this::autodetect));
|
||||||
panel.row("Toolchain Location", (r) -> {
|
|
||||||
r.cell(toolchainPathChooserComboBox)
|
|
||||||
.align(AlignX.FILL);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
});
|
||||||
|
p2.cell("Toolchain version", toolchainVersion);
|
||||||
panel.row("Toolchain Version", (r) -> {
|
p2.cell("Standard library location", pathToStdField, AlignX.FILL);
|
||||||
r.cell(toolchainVersion);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
panel.row("Standard Library Location", (r) -> {
|
|
||||||
r.cell(pathToStdField)
|
|
||||||
.align(AlignX.FILL);
|
|
||||||
return null;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
disposed = true;
|
disposed = true;
|
||||||
Disposer.dispose(toolchainPathChooserComboBox);
|
Disposer.dispose(pathToToolchain);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUI() {
|
private void updateUI() {
|
||||||
val pathToToolchain = toolchainPathChooserComboBox.getSelectedPath();
|
val pathToToolchain = PathUtil.pathFromString(this.pathToToolchain.getText());
|
||||||
|
|
||||||
versionUpdateDebouncer.run(
|
versionUpdateDebouncer.run(
|
||||||
() -> {
|
() -> {
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.ide.project;
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.common.util.TextFieldUtil;
|
|
||||||
import com.intellij.openapi.fileChooser.FileChooser;
|
|
||||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
|
||||||
import com.intellij.openapi.ui.ComboBoxWithWidePopup;
|
|
||||||
import com.intellij.openapi.ui.ComponentWithBrowseButton;
|
|
||||||
import com.intellij.ui.AnimatedIcon;
|
|
||||||
import com.intellij.ui.ComboboxSpeedSearch;
|
|
||||||
import com.intellij.ui.components.fields.ExtendableTextComponent;
|
|
||||||
import com.intellij.ui.components.fields.ExtendableTextField;
|
|
||||||
import lombok.val;
|
|
||||||
|
|
||||||
import javax.swing.JTextField;
|
|
||||||
import javax.swing.plaf.basic.BasicComboBoxEditor;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public class ZigToolchainPathChooserComboBox extends ComponentWithBrowseButton<ComboBoxWithWidePopup<Path>> {
|
|
||||||
public Runnable onTextChanged;
|
|
||||||
|
|
||||||
private final BasicComboBoxEditor comboBoxEditor = new BasicComboBoxEditor() {
|
|
||||||
@Override
|
|
||||||
protected JTextField createEditorComponent() {
|
|
||||||
return new ExtendableTextField();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private ExtendableTextField getPathTextField() {
|
|
||||||
return (ExtendableTextField) getChildComponent().getEditor().getEditorComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ExtendableTextComponent.Extension busyIconExtension = hovered -> AnimatedIcon.Default.INSTANCE;
|
|
||||||
|
|
||||||
public Path getSelectedPath() {
|
|
||||||
return Path.of(getPathTextField().getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelectedPath(Path path) {
|
|
||||||
if (path == null) {
|
|
||||||
getPathTextField().setText("");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
getPathTextField().setText(path.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZigToolchainPathChooserComboBox(Runnable onTextChanged) {
|
|
||||||
super(new ComboBoxWithWidePopup<>(), null);
|
|
||||||
this.onTextChanged = onTextChanged;
|
|
||||||
|
|
||||||
ComboboxSpeedSearch.installOn(getChildComponent());
|
|
||||||
getChildComponent().setEditor(comboBoxEditor);
|
|
||||||
getChildComponent().setEditable(true);
|
|
||||||
|
|
||||||
addActionListener(e -> {
|
|
||||||
val descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
|
|
||||||
//noinspection UsagesOfObsoleteApi
|
|
||||||
FileChooser.chooseFile(descriptor, null, null, (file) -> getChildComponent().setSelectedItem(file.toNioPath()));
|
|
||||||
});
|
|
||||||
|
|
||||||
TextFieldUtil.addTextChangeListener(getPathTextField(), ignored -> onTextChanged.run());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.ide.util.projectwizard;
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.ide.newproject.ZigNewProjectPanel;
|
|
||||||
import com.falsepattern.zigbrains.project.util.ExperimentUtil;
|
|
||||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
|
||||||
import com.intellij.openapi.util.Disposer;
|
|
||||||
import com.intellij.util.ui.JBUI;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
|
|
||||||
import static com.intellij.ui.dsl.builder.BuilderKt.panel;
|
|
||||||
|
|
||||||
public class ZigModuleWizardStep extends ModuleWizardStep {
|
|
||||||
private final ZigNewProjectPanel newProjectPanel = new ZigNewProjectPanel();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JComponent getComponent() {
|
|
||||||
return withBorderIfNeeded(panel((p) -> {
|
|
||||||
newProjectPanel.attachPanelTo(p);
|
|
||||||
return null;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disposeUIResources() {
|
|
||||||
Disposer.dispose(newProjectPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateDataModel() {
|
|
||||||
throw new UnsupportedOperationException("Not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T extends JComponent> T withBorderIfNeeded(T component) {
|
|
||||||
if (ExperimentUtil.isNewWizard()) {
|
|
||||||
component.setBorder(JBUI.Borders.empty(14, 20));
|
|
||||||
}
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,26 +16,16 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.openapi.components;
|
package com.falsepattern.zigbrains.project.openapi.components;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.WrappingStateComponent;
|
||||||
import com.intellij.openapi.components.PersistentStateComponent;
|
import com.intellij.openapi.components.PersistentStateComponent;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class AbstractZigProjectSettingsService<T> implements PersistentStateComponent<T> {
|
public abstract class AbstractZigProjectSettingsService<T> extends WrappingStateComponent<T> {
|
||||||
public final transient Project project;
|
public final transient Project project;
|
||||||
private final T state;
|
|
||||||
public AbstractZigProjectSettingsService(Project project, @NotNull T initialState) {
|
public AbstractZigProjectSettingsService(Project project, @NotNull T initialState) {
|
||||||
|
super(initialState);
|
||||||
this.project = project;
|
this.project = project;
|
||||||
this.state = initialState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull T getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadState(@NotNull T state) {
|
|
||||||
XmlSerializerUtil.copyBean(state, this.state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,20 +20,23 @@ import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider;
|
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider;
|
||||||
import com.intellij.util.io.PathKt;
|
import com.intellij.util.io.PathKt;
|
||||||
import com.intellij.util.xmlb.annotations.Transient;
|
import com.intellij.util.xmlb.annotations.Transient;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class ZigProjectSettings {
|
public class ZigProjectSettings {
|
||||||
public String toolchainHomeDirectory = null;
|
public String explicitPathToStd;
|
||||||
public String explicitPathToStd = null;
|
public String toolchainHomeDirectory;
|
||||||
|
|
||||||
public String getExplicitPathToStd() {
|
public ZigProjectSettings(String explicitPathToStd, AbstractZigToolchain toolchain) {
|
||||||
return explicitPathToStd;
|
this(explicitPathToStd, (String)null);
|
||||||
}
|
setToolchain(toolchain);
|
||||||
|
|
||||||
public void setExplicitPathToStd(String value) {
|
|
||||||
explicitPathToStd = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
|
@ -50,7 +53,7 @@ public class ZigProjectSettings {
|
||||||
toolchainHomeDirectory = null;
|
toolchainHomeDirectory = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var loc = value.location;
|
var loc = value.getLocation();
|
||||||
if (loc == null) {
|
if (loc == null) {
|
||||||
toolchainHomeDirectory = null;
|
toolchainHomeDirectory = null;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -16,13 +16,17 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.openapi.components;
|
package com.falsepattern.zigbrains.project.openapi.components;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.ide.project.ZigProjectSettingsPanel;
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||||
|
import com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity;
|
||||||
import com.intellij.openapi.components.Service;
|
import com.intellij.openapi.components.Service;
|
||||||
import com.intellij.openapi.components.State;
|
import com.intellij.openapi.components.State;
|
||||||
import com.intellij.openapi.components.Storage;
|
import com.intellij.openapi.components.Storage;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Service(Service.Level.PROJECT)
|
@Service(Service.Level.PROJECT)
|
||||||
|
@ -39,16 +43,9 @@ public final class ZigProjectSettingsService extends AbstractZigProjectSettingsS
|
||||||
return project.getService(ZigProjectSettingsService.class);
|
return project.getService(ZigProjectSettingsService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable AbstractZigToolchain getToolchain() {
|
public boolean isModified(ZigProjectSettings otherData) {
|
||||||
return getState().getToolchain();
|
val myData = getState();
|
||||||
}
|
return !Objects.equals(myData.toolchainHomeDirectory, otherData.toolchainHomeDirectory) ||
|
||||||
|
!Objects.equals(myData.explicitPathToStd, otherData.explicitPathToStd);
|
||||||
public @Nullable String getExplicitPathToStd() {
|
|
||||||
return getState().getExplicitPathToStd();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void modify(Consumer<ZigProjectSettings> modifier) {
|
|
||||||
var state = getState();
|
|
||||||
modifier.accept(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.openapi.module;
|
package com.falsepattern.zigbrains.project.openapi.module;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.ide.util.projectwizard.ZigModuleBuilder;
|
import com.falsepattern.zigbrains.project.ide.newproject.ZigModuleBuilder;
|
||||||
import com.falsepattern.zigbrains.zig.Icons;
|
import com.falsepattern.zigbrains.zig.Icons;
|
||||||
import com.intellij.openapi.module.ModuleType;
|
import com.intellij.openapi.module.ModuleType;
|
||||||
import org.jetbrains.annotations.Nls;
|
import org.jetbrains.annotations.Nls;
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.platform;
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.ide.newproject.ZigProjectConfigurationData;
|
|
||||||
import com.falsepattern.zigbrains.project.ide.project.ZigDefaultTemplate;
|
|
||||||
import com.falsepattern.zigbrains.project.ide.util.projectwizard.ZigProjectSettingsStep;
|
|
||||||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
|
||||||
import com.falsepattern.zigbrains.zig.Icons;
|
|
||||||
import com.intellij.facet.ui.ValidationResult;
|
|
||||||
import com.intellij.ide.util.projectWizard.AbstractNewProjectStep;
|
|
||||||
import com.intellij.ide.util.projectWizard.CustomStepProjectGenerator;
|
|
||||||
import com.intellij.notification.Notification;
|
|
||||||
import com.intellij.notification.NotificationType;
|
|
||||||
import com.intellij.notification.Notifications;
|
|
||||||
import com.intellij.openapi.application.WriteAction;
|
|
||||||
import com.intellij.openapi.module.Module;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.openapi.util.NlsContexts;
|
|
||||||
import com.intellij.openapi.vfs.VfsUtil;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
import com.intellij.openapi.wm.impl.welcomeScreen.AbstractActionWithPanel;
|
|
||||||
import com.intellij.platform.DirectoryProjectGenerator;
|
|
||||||
import com.intellij.platform.ProjectGeneratorPeer;
|
|
||||||
import com.intellij.util.ResourceUtil;
|
|
||||||
import lombok.val;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.Icon;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
public class ZigDirectoryProjectGenerator implements DirectoryProjectGenerator<ZigProjectConfigurationData>,
|
|
||||||
CustomStepProjectGenerator<ZigProjectConfigurationData> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull @NlsContexts.Label String getName() {
|
|
||||||
return "Zig";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Icon getLogo() {
|
|
||||||
return Icons.ZIG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ProjectGeneratorPeer<ZigProjectConfigurationData> createPeer() {
|
|
||||||
return new ZigProjectGeneratorPeer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ValidationResult validate(@NotNull String baseDirPath) {
|
|
||||||
return ValidationResult.OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getResourceString(String path) throws IOException {
|
|
||||||
byte[] data = ResourceUtil.getResourceAsBytes(path, ZigDirectoryProjectGenerator.class.getClassLoader());
|
|
||||||
if (data == null)
|
|
||||||
throw new IOException("Could not find resource " + path + "!");
|
|
||||||
return new String(data, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateProject(@NotNull Project project, @NotNull VirtualFile baseDir, @NotNull ZigProjectConfigurationData data, @NotNull Module module) {
|
|
||||||
val settings = data.settings();
|
|
||||||
|
|
||||||
var svc = ZigProjectSettingsService.getInstance(project);
|
|
||||||
val toolchain = settings.toolchain();
|
|
||||||
svc.getState().setToolchain(toolchain);
|
|
||||||
|
|
||||||
val template = data.selectedTemplate();
|
|
||||||
|
|
||||||
if (template instanceof ZigDefaultTemplate.ZigInitTemplate) {
|
|
||||||
if (toolchain == null) {
|
|
||||||
Notifications.Bus.notify(new Notification("ZigBrains.Project",
|
|
||||||
"Tried to generate project with zig init, but zig toolchain is invalid!",
|
|
||||||
NotificationType.ERROR));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
val zig = toolchain.zig();
|
|
||||||
val resultOpt = zig.callWithArgs(baseDir.toNioPath(), 10000, "init");
|
|
||||||
if (resultOpt.isEmpty()) {
|
|
||||||
Notifications.Bus.notify(new Notification("ZigBrains.Project",
|
|
||||||
"Failed to invoke \"zig init\"!",
|
|
||||||
NotificationType.ERROR));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
val result = resultOpt.get();
|
|
||||||
if (result.getExitCode() != 0) {
|
|
||||||
Notifications.Bus.notify(new Notification("ZigBrains.Project",
|
|
||||||
"\"zig init\" failed with exit code " + result.getExitCode() + "! Check the IDE log files!",
|
|
||||||
NotificationType.ERROR));
|
|
||||||
System.err.println(result.getStderr());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
val projectName = project.getName();
|
|
||||||
WriteAction.run(() -> {
|
|
||||||
for (val fileTemplate : template.fileTemplates().entrySet()) {
|
|
||||||
var fileName = fileTemplate.getKey();
|
|
||||||
VirtualFile parentDir;
|
|
||||||
if (fileName.contains("/")) {
|
|
||||||
val slashIndex = fileName.indexOf('/');
|
|
||||||
parentDir = baseDir.createChildDirectory(this, fileName.substring(0, slashIndex));
|
|
||||||
fileName = fileName.substring(slashIndex + 1);
|
|
||||||
} else {
|
|
||||||
parentDir = baseDir;
|
|
||||||
}
|
|
||||||
val templateDir = fileTemplate.getValue();
|
|
||||||
val resourceData = getResourceString("project-gen/" + templateDir + "/" + fileName + ".template").replace("@@PROJECT_NAME@@", projectName);
|
|
||||||
val targetFile = parentDir.createChildData(this, fileName);
|
|
||||||
VfsUtil.saveText(targetFile, resourceData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractActionWithPanel createStep(DirectoryProjectGenerator<ZigProjectConfigurationData> projectGenerator, AbstractNewProjectStep.AbstractCallback<ZigProjectConfigurationData> callback) {
|
|
||||||
return new ZigProjectSettingsStep(projectGenerator);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -52,7 +52,7 @@ public abstract class ZigProgramRunnerBase<ProfileState extends ProfileStateBase
|
||||||
if (state == null)
|
if (state == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
val toolchain = ZigProjectSettingsService.getInstance(environment.getProject()).getToolchain();
|
val toolchain = ZigProjectSettingsService.getInstance(environment.getProject()).getState().getToolchain();
|
||||||
if (toolchain == null) {
|
if (toolchain == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package com.falsepattern.zigbrains.project.toolchain;
|
||||||
import com.falsepattern.zigbrains.project.toolchain.flavours.AbstractZigToolchainFlavour;
|
import com.falsepattern.zigbrains.project.toolchain.flavours.AbstractZigToolchainFlavour;
|
||||||
import com.falsepattern.zigbrains.project.toolchain.tools.ZigCompilerTool;
|
import com.falsepattern.zigbrains.project.toolchain.tools.ZigCompilerTool;
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -26,8 +27,9 @@ import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Getter
|
||||||
public abstract class AbstractZigToolchain {
|
public abstract class AbstractZigToolchain {
|
||||||
public final Path location;
|
private final Path location;
|
||||||
|
|
||||||
public static @Nullable AbstractZigToolchain suggest() {
|
public static @Nullable AbstractZigToolchain suggest() {
|
||||||
return suggest(null);
|
return suggest(null);
|
||||||
|
|
|
@ -38,6 +38,6 @@ public class LocalZigToolchain extends AbstractZigToolchain{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path pathToExecutable(String toolName) {
|
public Path pathToExecutable(String toolName) {
|
||||||
return PathUtil.pathToExecutable(location, toolName);
|
return PathUtil.pathToExecutable(getLocation(), toolName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,9 @@ import java.nio.file.Path;
|
||||||
public class ToolchainZLSConfigProvider implements ZLSConfigProvider {
|
public class ToolchainZLSConfigProvider implements ZLSConfigProvider {
|
||||||
@Override
|
@Override
|
||||||
public void getEnvironment(Project project, ZLSConfig.ZLSConfigBuilder builder) {
|
public void getEnvironment(Project project, ZLSConfig.ZLSConfigBuilder builder) {
|
||||||
val projectSettings = ZigProjectSettingsService.getInstance(project);
|
val svc = ZigProjectSettingsService.getInstance(project);
|
||||||
val toolchain = projectSettings.getToolchain();
|
val state = svc.getState();
|
||||||
|
val toolchain = state.getToolchain();
|
||||||
if (toolchain == null)
|
if (toolchain == null)
|
||||||
return;
|
return;
|
||||||
val projectDir = ProjectUtil.guessProjectDir(project);
|
val projectDir = ProjectUtil.guessProjectDir(project);
|
||||||
|
|
|
@ -32,13 +32,13 @@
|
||||||
<runLineMarkerContributor language="Zig"
|
<runLineMarkerContributor language="Zig"
|
||||||
implementationClass="com.falsepattern.zigbrains.project.execution.build.ZigLineMarkerBuild"/>
|
implementationClass="com.falsepattern.zigbrains.project.execution.build.ZigLineMarkerBuild"/>
|
||||||
|
|
||||||
<directoryProjectGenerator implementation="com.falsepattern.zigbrains.project.platform.ZigDirectoryProjectGenerator"/>
|
<directoryProjectGenerator implementation="com.falsepattern.zigbrains.project.ide.newproject.ZigDirectoryProjectGenerator"/>
|
||||||
<newProjectWizard.languageGenerator implementation="com.falsepattern.zigbrains.project.ide.newproject.ZigNewProjectWizard"/>
|
<newProjectWizard.languageGenerator implementation="com.falsepattern.zigbrains.project.ide.newproject.ZigNewProjectWizard"/>
|
||||||
|
|
||||||
<moduleBuilder builderClass="com.falsepattern.zigbrains.project.ide.util.projectwizard.ZigModuleBuilder"/>
|
<moduleBuilder builderClass="com.falsepattern.zigbrains.project.ide.util.projectwizard.ZigModuleBuilder"/>
|
||||||
<projectConfigurable parentId="language"
|
<projectConfigurable parentId="language"
|
||||||
instance="com.falsepattern.zigbrains.project.ide.project.ZigProjectConfigurable"
|
instance="com.falsepattern.zigbrains.project.ide.config.ZigConfigurable"
|
||||||
id="com.falsepattern.zigbrains.project.ide.project.ZigProjectConfigurable"
|
id="com.falsepattern.zigbrains.project.ide.config.ZigConfigurable"
|
||||||
displayName="Zig"/>
|
displayName="Zig"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
zig-cache/
|
||||||
|
zig-out/
|
||||||
|
build/
|
||||||
|
build-*/
|
||||||
|
docgen_tmp/
|
|
@ -17,7 +17,7 @@
|
||||||
package com.falsepattern.zigbrains.zig.ide;
|
package com.falsepattern.zigbrains.zig.ide;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.lsp.contributors.LSPFoldingRangeProvider;
|
import com.falsepattern.zigbrains.lsp.contributors.LSPFoldingRangeProvider;
|
||||||
import com.falsepattern.zigbrains.zig.settings.ZLSSettingsState;
|
import com.falsepattern.zigbrains.zig.settings.ZLSProjectSettingsService;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import org.eclipse.lsp4j.FoldingRange;
|
import org.eclipse.lsp4j.FoldingRange;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -42,6 +42,6 @@ public class ZigFoldingRangeProvider extends LSPFoldingRangeProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean async(Project project) {
|
protected boolean async(Project project) {
|
||||||
return ZLSSettingsState.getInstance(project).asyncFolding;
|
return ZLSProjectSettingsService.getInstance(project).getState().asyncFolding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.zig.lsp;
|
package com.falsepattern.zigbrains.zig.lsp;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.common.util.StringUtil;
|
import com.falsepattern.zigbrains.common.util.StringUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
||||||
import com.falsepattern.zigbrains.lsp.utils.FileUtils;
|
import com.falsepattern.zigbrains.lsp.utils.FileUtils;
|
||||||
import com.falsepattern.zigbrains.zig.environment.ZLSConfigProvider;
|
import com.falsepattern.zigbrains.zig.environment.ZLSConfigProvider;
|
||||||
import com.falsepattern.zigbrains.zig.settings.ZLSSettingsState;
|
import com.falsepattern.zigbrains.zig.settings.ZLSProjectSettingsService;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.intellij.notification.Notification;
|
import com.intellij.notification.Notification;
|
||||||
import com.intellij.notification.NotificationType;
|
import com.intellij.notification.NotificationType;
|
||||||
|
@ -54,23 +55,23 @@ public class ZLSStartupActivity implements ProjectActivity {
|
||||||
for (var wrapper : wrappers) {
|
for (var wrapper : wrappers) {
|
||||||
if (wrapper.serverDefinition.ext.equals("zig")) {
|
if (wrapper.serverDefinition.ext.equals("zig")) {
|
||||||
wrapper.stop(false);
|
wrapper.stop(false);
|
||||||
wrapper.removeWidget();
|
|
||||||
IntellijLanguageClient.removeWrapper(wrapper);
|
IntellijLanguageClient.removeWrapper(wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var settings = ZLSSettingsState.getInstance(project);
|
var svc = ZLSProjectSettingsService.getInstance(project);
|
||||||
var zlsPath = settings.zlsPath;
|
val state = svc.getState();
|
||||||
|
var zlsPath = state.zlsPath;
|
||||||
if (!validatePath("ZLS Binary", zlsPath, false)) {
|
if (!validatePath("ZLS Binary", zlsPath, false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var configPath = settings.zlsConfigPath;
|
var configPath = state.zlsConfigPath;
|
||||||
boolean configOK = true;
|
boolean configOK = true;
|
||||||
if (!"".equals(configPath) && !validatePath("ZLS Config", configPath, false)) {
|
if (!configPath.isEmpty() && !validatePath("ZLS Config", configPath, false)) {
|
||||||
Notifications.Bus.notify(new Notification("ZigBrains.ZLS", "Using default config path.",
|
Notifications.Bus.notify(new Notification("ZigBrains.ZLS", "Using default config path.",
|
||||||
NotificationType.INFORMATION));
|
NotificationType.INFORMATION));
|
||||||
configPath = "";
|
configPath = null;
|
||||||
}
|
}
|
||||||
if ("".equals(configPath)) {
|
if (configPath == null || configPath.isBlank()) {
|
||||||
blk:
|
blk:
|
||||||
try {
|
try {
|
||||||
val tmpFile = Files.createTempFile("zigbrains-zls-autoconf", ".json");
|
val tmpFile = Files.createTempFile("zigbrains-zls-autoconf", ".json");
|
||||||
|
@ -103,16 +104,16 @@ public class ZLSStartupActivity implements ProjectActivity {
|
||||||
cmd.add(configPath);
|
cmd.add(configPath);
|
||||||
}
|
}
|
||||||
// TODO make this properly configurable
|
// TODO make this properly configurable
|
||||||
if (settings.increaseTimeouts) {
|
if (state.increaseTimeouts) {
|
||||||
for (var timeout : IntellijLanguageClient.getTimeouts().keySet()) {
|
for (var timeout : IntellijLanguageClient.getTimeouts().keySet()) {
|
||||||
IntellijLanguageClient.setTimeout(timeout, 15000);
|
IntellijLanguageClient.setTimeout(timeout, 15000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.debug) {
|
if (state.debug) {
|
||||||
cmd.add("--enable-debug-log");
|
cmd.add("--enable-debug-log");
|
||||||
}
|
}
|
||||||
if (settings.messageTrace) {
|
if (state.messageTrace) {
|
||||||
cmd.add("--enable-message-tracing");
|
cmd.add("--enable-message-tracing");
|
||||||
}
|
}
|
||||||
for (var wrapper : IntellijLanguageClient.getAllServerWrappersFor("zig")) {
|
for (var wrapper : IntellijLanguageClient.getAllServerWrappersFor("zig")) {
|
||||||
|
@ -133,12 +134,16 @@ public class ZLSStartupActivity implements ProjectActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean validatePath(String name, String pathTxt, boolean dir) {
|
private static boolean validatePath(String name, String pathTxt, boolean dir) {
|
||||||
|
if (pathTxt == null || pathTxt.isBlank()) {
|
||||||
|
Notifications.Bus.notify(new Notification("ZigBrains.ZLS", "Missing " + name, "No path was specified", NotificationType.WARNING));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Path path;
|
Path path;
|
||||||
try {
|
try {
|
||||||
path = Path.of(pathTxt);
|
path = Path.of(pathTxt);
|
||||||
} catch (InvalidPathException e) {
|
} catch (InvalidPathException e) {
|
||||||
Notifications.Bus.notify(
|
Notifications.Bus.notify(
|
||||||
new Notification("ZigBrains.ZLS", "No " + name, "Invalid " + name + " path \"" + pathTxt + "\"",
|
new Notification("ZigBrains.ZLS", "No " + name, "Invalid " + name + " at path \"" + pathTxt + "\"",
|
||||||
NotificationType.ERROR));
|
NotificationType.ERROR));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +157,7 @@ public class ZLSStartupActivity implements ProjectActivity {
|
||||||
Notifications.Bus.notify(new Notification("ZigBrains.ZLS", "No " + name,
|
Notifications.Bus.notify(new Notification("ZigBrains.ZLS", "No " + name,
|
||||||
"The " + name + " at \"" + pathTxt + "\" is a " +
|
"The " + name + " at \"" + pathTxt + "\" is a " +
|
||||||
(Files.isDirectory(path) ? "directory" : "file") +
|
(Files.isDirectory(path) ? "directory" : "file") +
|
||||||
" , expected a " + (dir ? "directory" : "file"),
|
", expected a " + (dir ? "directory" : "file"),
|
||||||
NotificationType.ERROR));
|
NotificationType.ERROR));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -162,16 +167,15 @@ public class ZLSStartupActivity implements ProjectActivity {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Object execute(@NotNull Project project, @NotNull Continuation<? super Unit> continuation) {
|
public Object execute(@NotNull Project project, @NotNull Continuation<? super Unit> continuation) {
|
||||||
var settings = ZLSSettingsState.getInstance(project);
|
val svc = ZLSProjectSettingsService.getInstance(project);
|
||||||
var zlsPath = settings.zlsPath;
|
val state = svc.getState();
|
||||||
|
var zlsPath = state.zlsPath;
|
||||||
|
|
||||||
if (zlsPath.isEmpty() && !settings.initialAutodetectHasBeenDone) {
|
if (zlsPath == null) {
|
||||||
settings.initialAutodetectHasBeenDone = true;
|
//Project creation
|
||||||
var thePath = ZLSSettingsState.executablePathFinder("zls");
|
return null;
|
||||||
if (thePath.isPresent()) {
|
|
||||||
zlsPath = settings.zlsPath = thePath.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zlsPath.isEmpty()) {
|
if (zlsPath.isEmpty()) {
|
||||||
Notifications.Bus.notify(new Notification("ZigBrains.ZLS", "No ZLS binary",
|
Notifications.Bus.notify(new Notification("ZigBrains.ZLS", "No ZLS binary",
|
||||||
"Please configure the path to the zls executable in the Zig language configuration menu!",
|
"Please configure the path to the zls executable in the Zig language configuration menu!",
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* 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.zig.settings;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.WrappingStateComponent;
|
||||||
|
import com.intellij.openapi.components.Service;
|
||||||
|
import com.intellij.openapi.components.State;
|
||||||
|
import com.intellij.openapi.components.Storage;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.SystemInfo;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service(Service.Level.PROJECT)
|
||||||
|
@State(name = "ZLSSettings",
|
||||||
|
storages = @Storage("zigbrains.xml"))
|
||||||
|
public final class ZLSProjectSettingsService extends WrappingStateComponent<ZLSSettings> {
|
||||||
|
public ZLSProjectSettingsService() {
|
||||||
|
super(new ZLSSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ZLSProjectSettingsService getInstance(Project project) {
|
||||||
|
return project.getService(ZLSProjectSettingsService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModified(ZLSSettings otherData) {
|
||||||
|
val myData = this.getState();
|
||||||
|
boolean modified = zlsSettingsModified(otherData);
|
||||||
|
modified |= myData.asyncFolding != otherData.asyncFolding;
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean zlsSettingsModified(ZLSSettings otherData) {
|
||||||
|
val myData = this.getState();
|
||||||
|
boolean modified = !Objects.equals(myData.zlsPath, otherData.zlsPath);
|
||||||
|
modified |= !Objects.equals(myData.zlsConfigPath, otherData.zlsConfigPath);
|
||||||
|
modified |= myData.debug != otherData.debug;
|
||||||
|
modified |= myData.messageTrace != otherData.messageTrace;
|
||||||
|
modified |= myData.increaseTimeouts != otherData.increaseTimeouts;
|
||||||
|
modified |= myData.buildOnSave != otherData.buildOnSave;
|
||||||
|
modified |= !Objects.equals(myData.buildOnSaveStep, otherData.buildOnSaveStep);
|
||||||
|
modified |= myData.highlightGlobalVarDeclarations != otherData.highlightGlobalVarDeclarations;
|
||||||
|
modified |= myData.dangerousComptimeExperimentsDoNotEnable != otherData.dangerousComptimeExperimentsDoNotEnable;
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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.zig.settings;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public final class ZLSSettings {
|
||||||
|
public @Nullable String zlsPath;
|
||||||
|
public @NotNull String zlsConfigPath;
|
||||||
|
public boolean increaseTimeouts;
|
||||||
|
public boolean asyncFolding;
|
||||||
|
public boolean debug;
|
||||||
|
public boolean messageTrace;
|
||||||
|
public boolean buildOnSave;
|
||||||
|
public @NotNull String buildOnSaveStep;
|
||||||
|
public boolean highlightGlobalVarDeclarations;
|
||||||
|
public boolean dangerousComptimeExperimentsDoNotEnable;
|
||||||
|
|
||||||
|
public ZLSSettings() {
|
||||||
|
this(null, "", false, true, false, false, false, "install", false, false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,174 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.zig.settings;
|
|
||||||
|
|
||||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
|
||||||
import com.intellij.openapi.ui.TextBrowseFolderListener;
|
|
||||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
|
||||||
import com.intellij.ui.components.JBCheckBox;
|
|
||||||
import com.intellij.ui.components.JBLabel;
|
|
||||||
import com.intellij.ui.components.JBTextField;
|
|
||||||
import com.intellij.util.ui.FormBuilder;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
public class ZLSSettingsComponent {
|
|
||||||
private final JPanel myMainPanel;
|
|
||||||
private final TextFieldWithBrowseButton zlsPathText = new TextFieldWithBrowseButton();
|
|
||||||
private final TextFieldWithBrowseButton zlsConfigPathText = new TextFieldWithBrowseButton();
|
|
||||||
private final JBCheckBox asyncFoldingCheckBox = new JBCheckBox();
|
|
||||||
private final JBCheckBox increaseTimeouts = new JBCheckBox();
|
|
||||||
|
|
||||||
private final JBCheckBox buildOnSave = new JBCheckBox();
|
|
||||||
private final JBTextField buildOnSaveStep = new JBTextField();
|
|
||||||
private final JBCheckBox highlightGlobalVarDeclarations = new JBCheckBox();
|
|
||||||
private final JBCheckBox dangerousComptimeExperimentsDoNotEnable = new JBCheckBox();
|
|
||||||
|
|
||||||
private final JBCheckBox messageTraceCheckBox = new JBCheckBox();
|
|
||||||
private final JBCheckBox debugCheckBox = new JBCheckBox();
|
|
||||||
|
|
||||||
private final JButton autodetectZls = new JButton("Autodetect");
|
|
||||||
|
|
||||||
{
|
|
||||||
buildOnSave.setToolTipText("Whether to enable build-on-save diagnostics");
|
|
||||||
buildOnSaveStep.setToolTipText("Select which step should be executed on build-on-save");
|
|
||||||
highlightGlobalVarDeclarations.setToolTipText("Whether to highlight global var declarations");
|
|
||||||
dangerousComptimeExperimentsDoNotEnable.setToolTipText("Whether to use the comptime interpreter");
|
|
||||||
}
|
|
||||||
public ZLSSettingsComponent() {
|
|
||||||
zlsPathText.addBrowseFolderListener(
|
|
||||||
new TextBrowseFolderListener(new FileChooserDescriptor(true, false, false, false, false, false)));
|
|
||||||
myMainPanel = FormBuilder.createFormBuilder()
|
|
||||||
.addComponent(new JBLabel("ZLS launch settings"))
|
|
||||||
.addVerticalGap(10)
|
|
||||||
.addLabeledComponent(new JBLabel("ZLS path: "), zlsPathText, 1, false)
|
|
||||||
.addComponent(autodetectZls)
|
|
||||||
.addLabeledComponent(new JBLabel("ZLS config path (leave empty to use built-in config): "),
|
|
||||||
zlsConfigPathText, 1, false)
|
|
||||||
.addLabeledComponent(new JBLabel("Increase timeouts"), increaseTimeouts, 1, false)
|
|
||||||
.addLabeledComponent(new JBLabel("Asynchronous code folding ranges: "),
|
|
||||||
asyncFoldingCheckBox, 1, false)
|
|
||||||
.addSeparator()
|
|
||||||
.addComponent(new JBLabel("ZLS configuration"))
|
|
||||||
.addVerticalGap(10)
|
|
||||||
.addLabeledComponent("Build on save", buildOnSave)
|
|
||||||
.addLabeledComponent("Build on save step", buildOnSaveStep)
|
|
||||||
.addLabeledComponent("Highlight global variable declarations", highlightGlobalVarDeclarations)
|
|
||||||
.addLabeledComponent("Dangerous comptime experiments (do not enable)", dangerousComptimeExperimentsDoNotEnable)
|
|
||||||
.addSeparator()
|
|
||||||
.addComponent(new JBLabel(
|
|
||||||
"Developer settings (only usable when the IDE was launched with " +
|
|
||||||
"the runIDE gradle task in ZigBrains!)"))
|
|
||||||
.addVerticalGap(10)
|
|
||||||
.addLabeledComponent(new JBLabel("ZLS debug log: "), debugCheckBox, 1, false)
|
|
||||||
.addLabeledComponent(new JBLabel("ZLS message trace: "), messageTraceCheckBox, 1,
|
|
||||||
false)
|
|
||||||
.addComponentFillVertically(new JPanel(), 0)
|
|
||||||
.getPanel();
|
|
||||||
autodetectZls.addActionListener(e -> {
|
|
||||||
ZLSSettingsState.executablePathFinder("zls").ifPresent(this::setZLSPath);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public JPanel getPanel() {
|
|
||||||
return myMainPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public String getZLSPath() {
|
|
||||||
return zlsPathText.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setZLSPath(@NotNull String newText) {
|
|
||||||
zlsPathText.setText(newText);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public String getZLSConfigPath() {
|
|
||||||
return zlsConfigPathText.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setZLSConfigPath(@NotNull String newText) {
|
|
||||||
zlsConfigPathText.setText(newText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIncreaseTimeouts() {
|
|
||||||
return increaseTimeouts.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIncreaseTimeouts(boolean state) {
|
|
||||||
increaseTimeouts.setSelected(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getAsyncFolding() {
|
|
||||||
return asyncFoldingCheckBox.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAsyncFolding(boolean state) {
|
|
||||||
asyncFoldingCheckBox.setSelected(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getDebug() {
|
|
||||||
return debugCheckBox.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDebug(boolean state) {
|
|
||||||
debugCheckBox.setSelected(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getMessageTrace() {
|
|
||||||
return messageTraceCheckBox.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessageTrace(boolean state) {
|
|
||||||
messageTraceCheckBox.setSelected(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getBuildOnSave() {
|
|
||||||
return buildOnSave.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBuildOnSave(boolean state) {
|
|
||||||
buildOnSave.setSelected(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBuildOnSaveStep() {
|
|
||||||
return buildOnSaveStep.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBuildOnSaveStep(String value) {
|
|
||||||
buildOnSaveStep.setText(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getHighlightGlobalVarDeclarations() {
|
|
||||||
return highlightGlobalVarDeclarations.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHighlightGlobalVarDeclarations(boolean state) {
|
|
||||||
highlightGlobalVarDeclarations.setSelected(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getDangerousComptimeExperimentsDoNotEnable() {
|
|
||||||
return dangerousComptimeExperimentsDoNotEnable.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDangerousComptimeExperimentsDoNotEnable(boolean state) {
|
|
||||||
dangerousComptimeExperimentsDoNotEnable.setSelected(state);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,7 @@ import lombok.val;
|
||||||
public class ZLSSettingsConfigProvider implements ZLSConfigProvider {
|
public class ZLSSettingsConfigProvider implements ZLSConfigProvider {
|
||||||
@Override
|
@Override
|
||||||
public void getEnvironment(Project project, ZLSConfig.ZLSConfigBuilder builder) {
|
public void getEnvironment(Project project, ZLSConfig.ZLSConfigBuilder builder) {
|
||||||
val state = ZLSSettingsState.getInstance(project);
|
val state = ZLSProjectSettingsService.getInstance(project).getState();
|
||||||
builder.enable_build_on_save(state.buildOnSave);
|
builder.enable_build_on_save(state.buildOnSave);
|
||||||
builder.build_on_save_step(state.buildOnSaveStep);
|
builder.build_on_save_step(state.buildOnSaveStep);
|
||||||
builder.highlight_global_var_declarations(state.highlightGlobalVarDeclarations);
|
builder.highlight_global_var_declarations(state.highlightGlobalVarDeclarations);
|
||||||
|
|
|
@ -16,16 +16,15 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.zig.settings;
|
package com.falsepattern.zigbrains.zig.settings;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.SubConfigurable;
|
||||||
|
import com.falsepattern.zigbrains.common.util.dsl.JavaPanel;
|
||||||
import com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity;
|
import com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity;
|
||||||
import com.intellij.openapi.options.Configurable;
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
public class ZLSSettingsConfigurable implements SubConfigurable {
|
||||||
|
private ZLSSettingsPanel appSettingsComponent;
|
||||||
public class ZLSSettingsConfigurable implements Configurable {
|
|
||||||
private ZLSSettingsComponent appSettingsComponent;
|
|
||||||
|
|
||||||
private final Project project;
|
private final Project project;
|
||||||
|
|
||||||
|
@ -34,52 +33,24 @@ public class ZLSSettingsConfigurable implements Configurable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public void createComponent(JavaPanel panel) {
|
||||||
return "Zig";
|
appSettingsComponent = new ZLSSettingsPanel();
|
||||||
}
|
appSettingsComponent.attachPanelTo(panel);
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable JComponent createComponent() {
|
|
||||||
appSettingsComponent = new ZLSSettingsComponent();
|
|
||||||
return appSettingsComponent.getPanel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isModified() {
|
public boolean isModified() {
|
||||||
var settings = ZLSSettingsState.getInstance(project);
|
var settings = ZLSProjectSettingsService.getInstance(project);
|
||||||
boolean modified = zlsSettingsModified(settings);
|
val data = appSettingsComponent.getData();
|
||||||
modified |= settings.asyncFolding != appSettingsComponent.getAsyncFolding();
|
return settings.isModified(data);
|
||||||
return modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean zlsSettingsModified(ZLSSettingsState settings) {
|
|
||||||
boolean modified = !settings.zlsPath.equals(appSettingsComponent.getZLSPath());
|
|
||||||
modified |= !settings.zlsConfigPath.equals(appSettingsComponent.getZLSConfigPath());
|
|
||||||
modified |= settings.debug != appSettingsComponent.getDebug();
|
|
||||||
modified |= settings.messageTrace != appSettingsComponent.getMessageTrace();
|
|
||||||
modified |= settings.increaseTimeouts != appSettingsComponent.getIncreaseTimeouts();
|
|
||||||
modified |= settings.buildOnSave != appSettingsComponent.getBuildOnSave();
|
|
||||||
modified |= !settings.buildOnSaveStep.equals(appSettingsComponent.getBuildOnSaveStep());
|
|
||||||
modified |= settings.highlightGlobalVarDeclarations != appSettingsComponent.getHighlightGlobalVarDeclarations();
|
|
||||||
modified |= settings.dangerousComptimeExperimentsDoNotEnable != appSettingsComponent.getDangerousComptimeExperimentsDoNotEnable();
|
|
||||||
return modified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply() {
|
public void apply() {
|
||||||
var settings = ZLSSettingsState.getInstance(project);
|
var settings = ZLSProjectSettingsService.getInstance(project);
|
||||||
boolean reloadZLS = zlsSettingsModified(settings);
|
val data = appSettingsComponent.getData();
|
||||||
settings.zlsPath = appSettingsComponent.getZLSPath();
|
boolean reloadZLS = settings.zlsSettingsModified(data);
|
||||||
settings.zlsConfigPath = appSettingsComponent.getZLSConfigPath();
|
settings.loadState(data);
|
||||||
settings.asyncFolding = appSettingsComponent.getAsyncFolding();
|
|
||||||
settings.debug = appSettingsComponent.getDebug();
|
|
||||||
settings.messageTrace = appSettingsComponent.getMessageTrace();
|
|
||||||
settings.increaseTimeouts = appSettingsComponent.getIncreaseTimeouts();
|
|
||||||
|
|
||||||
settings.buildOnSave = appSettingsComponent.getBuildOnSave();
|
|
||||||
settings.buildOnSaveStep = appSettingsComponent.getBuildOnSaveStep();
|
|
||||||
settings.highlightGlobalVarDeclarations = appSettingsComponent.getHighlightGlobalVarDeclarations();
|
|
||||||
settings.dangerousComptimeExperimentsDoNotEnable = appSettingsComponent.getDangerousComptimeExperimentsDoNotEnable();
|
|
||||||
if (reloadZLS) {
|
if (reloadZLS) {
|
||||||
ZLSStartupActivity.initZLS(project);
|
ZLSStartupActivity.initZLS(project);
|
||||||
}
|
}
|
||||||
|
@ -87,19 +58,8 @@ public class ZLSSettingsConfigurable implements Configurable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
var settings = ZLSSettingsState.getInstance(project);
|
var settings = ZLSProjectSettingsService.getInstance(project);
|
||||||
appSettingsComponent.setZLSPath(settings.zlsPath);
|
appSettingsComponent.setData(settings.getState());
|
||||||
appSettingsComponent.setZLSConfigPath(settings.zlsConfigPath);
|
|
||||||
appSettingsComponent.setDebug(settings.debug);
|
|
||||||
appSettingsComponent.setAsyncFolding(settings.asyncFolding);
|
|
||||||
appSettingsComponent.setMessageTrace(settings.messageTrace);
|
|
||||||
appSettingsComponent.setIncreaseTimeouts(settings.increaseTimeouts);
|
|
||||||
appSettingsComponent.setAsyncFolding(settings.asyncFolding);
|
|
||||||
|
|
||||||
appSettingsComponent.setBuildOnSave(settings.buildOnSave);
|
|
||||||
appSettingsComponent.setBuildOnSaveStep(settings.buildOnSaveStep);
|
|
||||||
appSettingsComponent.setHighlightGlobalVarDeclarations(settings.highlightGlobalVarDeclarations);
|
|
||||||
appSettingsComponent.setDangerousComptimeExperimentsDoNotEnable(settings.dangerousComptimeExperimentsDoNotEnable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* 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.zig.settings;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
|
import com.falsepattern.zigbrains.common.util.TextFieldUtil;
|
||||||
|
import com.falsepattern.zigbrains.common.util.dsl.JavaPanel;
|
||||||
|
import com.intellij.openapi.Disposable;
|
||||||
|
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||||
|
import com.intellij.openapi.project.ProjectManager;
|
||||||
|
import com.intellij.openapi.ui.TextBrowseFolderListener;
|
||||||
|
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||||
|
import com.intellij.ui.components.JBCheckBox;
|
||||||
|
import com.intellij.ui.components.JBTextField;
|
||||||
|
import com.intellij.ui.components.fields.ExtendableTextField;
|
||||||
|
import com.intellij.ui.dsl.builder.AlignX;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static com.falsepattern.zigbrains.common.util.KtUtil.$f;
|
||||||
|
|
||||||
|
public class ZLSSettingsPanel implements Disposable {
|
||||||
|
private final TextFieldWithBrowseButton zlsPath = TextFieldUtil.pathToFileTextField(this,
|
||||||
|
"Path to the ZLS Binary",
|
||||||
|
() -> {});
|
||||||
|
private final TextFieldWithBrowseButton zlsConfigPath = TextFieldUtil.pathToFileTextField(this,
|
||||||
|
"Path to the Custom ZLS Config File (Optional)",
|
||||||
|
() -> {});
|
||||||
|
private final JBCheckBox asyncFolding = new JBCheckBox();
|
||||||
|
private final JBCheckBox increaseTimeouts = new JBCheckBox();
|
||||||
|
|
||||||
|
private final JBCheckBox buildOnSave = new JBCheckBox();
|
||||||
|
private final JBTextField buildOnSaveStep = new ExtendableTextField();
|
||||||
|
private final JBCheckBox highlightGlobalVarDeclarations = new JBCheckBox();
|
||||||
|
private final JBCheckBox dangerousComptimeExperimentsDoNotEnable = new JBCheckBox();
|
||||||
|
|
||||||
|
private final JBCheckBox messageTrace = new JBCheckBox();
|
||||||
|
private final JBCheckBox debug = new JBCheckBox();
|
||||||
|
|
||||||
|
{
|
||||||
|
buildOnSave.setToolTipText("Whether to enable build-on-save diagnostics");
|
||||||
|
buildOnSaveStep.setToolTipText("Select which step should be executed on build-on-save");
|
||||||
|
highlightGlobalVarDeclarations.setToolTipText("Whether to highlight global var declarations");
|
||||||
|
dangerousComptimeExperimentsDoNotEnable.setToolTipText("Whether to use the comptime interpreter");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void autodetect(ActionEvent e) {
|
||||||
|
autodetect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void autodetect() {
|
||||||
|
FileUtil.findExecutableOnPATH("zls").map(Path::toString).ifPresent(zlsPath::setText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZLSSettingsPanel() {
|
||||||
|
zlsPath.addBrowseFolderListener(new TextBrowseFolderListener(new FileChooserDescriptor(true, false, false, false, false, false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attachPanelTo(JavaPanel panel) {
|
||||||
|
Optional.ofNullable(ZLSProjectSettingsService.getInstance(ProjectManager.getInstance().getDefaultProject()))
|
||||||
|
.map(ZLSProjectSettingsService::getState)
|
||||||
|
.ifPresent(this::setData);
|
||||||
|
panel.group("ZLS launch settings", p -> {
|
||||||
|
p.row("Executable path", r -> {
|
||||||
|
r.cell(zlsPath).resizableColumn().align(AlignX.FILL);
|
||||||
|
r.button("Autodetect", $f(this::autodetect));
|
||||||
|
});
|
||||||
|
p.cell("Config path (leave empty to use built-in config)", zlsConfigPath, AlignX.FILL);
|
||||||
|
p.cell("Increase timeouts", increaseTimeouts);
|
||||||
|
p.cell("Asynchronous code folding ranges", asyncFolding);
|
||||||
|
});
|
||||||
|
panel.group("ZLS Configuration", p -> {
|
||||||
|
p.cell("Build on save", buildOnSave);
|
||||||
|
p.row("Build on save step", r -> {
|
||||||
|
r.cell(buildOnSaveStep).resizableColumn().align(AlignX.FILL);
|
||||||
|
});
|
||||||
|
p.cell("Highlight global variable declarations", highlightGlobalVarDeclarations);
|
||||||
|
p.cell("Dangerous comptime experiments (do not enable)", dangerousComptimeExperimentsDoNotEnable);
|
||||||
|
});
|
||||||
|
panel.group("ZLS Developer settings", p -> {
|
||||||
|
p.cell("Debug log", debug);
|
||||||
|
p.cell("Message trace", messageTrace);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZLSSettings getData() {
|
||||||
|
return new ZLSSettings(zlsPath.getText(),
|
||||||
|
zlsConfigPath.getText(),
|
||||||
|
increaseTimeouts.isSelected(),
|
||||||
|
asyncFolding.isSelected(),
|
||||||
|
debug.isSelected(),
|
||||||
|
messageTrace.isSelected(),
|
||||||
|
buildOnSave.isSelected(),
|
||||||
|
buildOnSaveStep.getText(),
|
||||||
|
highlightGlobalVarDeclarations.isSelected(),
|
||||||
|
dangerousComptimeExperimentsDoNotEnable.isSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(ZLSSettings value) {
|
||||||
|
zlsPath.setText(value.zlsPath == null ? "" : value.zlsPath);
|
||||||
|
zlsConfigPath.setText(value.zlsConfigPath);
|
||||||
|
increaseTimeouts.setSelected(value.increaseTimeouts);
|
||||||
|
asyncFolding.setSelected(value.asyncFolding);
|
||||||
|
debug.setSelected(value.debug);
|
||||||
|
messageTrace.setSelected(value.messageTrace);
|
||||||
|
buildOnSave.setSelected(value.buildOnSave);
|
||||||
|
buildOnSaveStep.setText(value.buildOnSaveStep);
|
||||||
|
highlightGlobalVarDeclarations.setSelected(value.highlightGlobalVarDeclarations);
|
||||||
|
dangerousComptimeExperimentsDoNotEnable.setSelected(value.dangerousComptimeExperimentsDoNotEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
zlsPath.dispose();
|
||||||
|
zlsConfigPath.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.zig.settings;
|
|
||||||
|
|
||||||
import com.intellij.openapi.components.PersistentStateComponent;
|
|
||||||
import com.intellij.openapi.components.Service;
|
|
||||||
import com.intellij.openapi.components.State;
|
|
||||||
import com.intellij.openapi.components.Storage;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.openapi.util.SystemInfo;
|
|
||||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service(Service.Level.PROJECT)
|
|
||||||
@State(name = "ZLSSettings",
|
|
||||||
storages = @Storage("zigbrains.xml"))
|
|
||||||
public final class ZLSSettingsState implements PersistentStateComponent<ZLSSettingsState> {
|
|
||||||
public String zlsPath = "";
|
|
||||||
public String zlsConfigPath = "";
|
|
||||||
public boolean initialAutodetectHasBeenDone = false;
|
|
||||||
public boolean increaseTimeouts = false;
|
|
||||||
public boolean asyncFolding = true;
|
|
||||||
public boolean debug = false;
|
|
||||||
public boolean messageTrace = false;
|
|
||||||
|
|
||||||
public boolean buildOnSave = false;
|
|
||||||
public String buildOnSaveStep = "install";
|
|
||||||
public boolean dangerousComptimeExperimentsDoNotEnable = false;
|
|
||||||
public boolean highlightGlobalVarDeclarations = false;
|
|
||||||
|
|
||||||
public static Optional<String> executablePathFinder(String exe) {
|
|
||||||
var exeName = SystemInfo.isWindows ? exe + ".exe" : exe;
|
|
||||||
var PATH = System.getenv("PATH").split(File.pathSeparator);
|
|
||||||
for (var dir: PATH) {
|
|
||||||
var path = Path.of(dir);
|
|
||||||
try {
|
|
||||||
path = path.toAbsolutePath();
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!Files.exists(path) || !Files.isDirectory(path)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var exePath = path.resolve(exeName).toAbsolutePath();
|
|
||||||
if (!Files.isRegularFile(exePath) || !Files.isExecutable(exePath)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return Optional.of(exePath.toString());
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ZLSSettingsState getInstance(Project project) {
|
|
||||||
return project.getService(ZLSSettingsState.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ZLSSettingsState getState() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadState(@NotNull ZLSSettingsState state) {
|
|
||||||
XmlSerializerUtil.copyBean(state, this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -98,11 +98,6 @@
|
||||||
|
|
||||||
<lang.formatter language="Zig" implementationClass="com.falsepattern.zigbrains.zig.formatter.ZigFormattingModelBuilder"/>
|
<lang.formatter language="Zig" implementationClass="com.falsepattern.zigbrains.zig.formatter.ZigFormattingModelBuilder"/>
|
||||||
|
|
||||||
<projectConfigurable parentId="language"
|
|
||||||
instance="com.falsepattern.zigbrains.zig.settings.ZLSSettingsConfigurable"
|
|
||||||
id="com.falsepattern.zigbrains.zig.settings.ZLSSettingsConfigurable"
|
|
||||||
displayName="ZLS"/>
|
|
||||||
|
|
||||||
<postStartupActivity implementation="com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity"/>
|
<postStartupActivity implementation="com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity"/>
|
||||||
<notificationGroup displayType="BALLOON"
|
<notificationGroup displayType="BALLOON"
|
||||||
bundle="zigbrains.zig.Bundle"
|
bundle="zigbrains.zig.Bundle"
|
||||||
|
|
Loading…
Add table
Reference in a new issue