feat(config): Reimplemented config backend, much more reliable and extensible now.
This commit is contained in:
parent
2d1620f86d
commit
bc408b1d50
18 changed files with 583 additions and 230 deletions
|
@ -39,6 +39,10 @@ Changelog structure reference:
|
||||||
|
|
||||||
- NullPointerException in folding range provider when closing editors quickly
|
- NullPointerException in folding range provider when closing editors quickly
|
||||||
|
|
||||||
|
#### Config
|
||||||
|
|
||||||
|
- Changes to the ZLS configuration no longer require an IDE restart
|
||||||
|
|
||||||
## [0.6.0]
|
## [0.6.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -27,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.editor.Document;
|
import com.intellij.openapi.editor.Document;
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.Key;
|
import com.intellij.openapi.util.Key;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
@ -46,7 +47,6 @@ import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class LSPFoldingRangeProvider extends CustomFoldingBuilder {
|
public class LSPFoldingRangeProvider extends CustomFoldingBuilder {
|
||||||
private static final Key<Boolean> ASYNC_FOLDING_KEY = new Key<>("ASYNC_FOLDING");
|
private static final Key<Boolean> ASYNC_FOLDING_KEY = new Key<>("ASYNC_FOLDING");
|
||||||
|
@ -76,7 +76,7 @@ public class LSPFoldingRangeProvider extends CustomFoldingBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var async = async();
|
var async = async(root.getProject());
|
||||||
if (!async) {
|
if (!async) {
|
||||||
doBuildLanguageFoldRegions((start, end, collapsedText) -> {
|
doBuildLanguageFoldRegions((start, end, collapsedText) -> {
|
||||||
if (collapsedText != null) {
|
if (collapsedText != null) {
|
||||||
|
@ -186,7 +186,7 @@ public class LSPFoldingRangeProvider extends CustomFoldingBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean async() {
|
protected boolean async(Project project) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings;
|
||||||
|
|
||||||
|
import com.intellij.openapi.options.Configurable;
|
||||||
|
import com.intellij.openapi.options.ConfigurationException;
|
||||||
|
import com.intellij.openapi.util.NlsContexts;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public abstract class AbstractConfigurable<T> implements Configurable {
|
||||||
|
private final String displayName;
|
||||||
|
private final Supplier<ConfigurableGui<T>> guiSupplier;
|
||||||
|
protected ConfigurableGui<T> configurableGui;
|
||||||
|
|
||||||
|
public AbstractConfigurable(MethodHandles.Lookup lookup, String displayName, Class<T> holderClass)
|
||||||
|
throws IllegalAccessException {
|
||||||
|
this.displayName = displayName;
|
||||||
|
guiSupplier = ConfigurableGui.create(lookup, holderClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T getHolder();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NlsContexts.ConfigurableName String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable JComponent createComponent() {
|
||||||
|
configurableGui = guiSupplier.get();
|
||||||
|
return configurableGui.getPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isModified() {
|
||||||
|
return configurableGui.modified(getHolder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply() throws ConfigurationException {
|
||||||
|
configurableGui.guiToConfig(getHolder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
configurableGui.configToGui(getHolder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disposeUIResources() {
|
||||||
|
configurableGui = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings;
|
||||||
|
|
||||||
|
import com.intellij.ui.TextAccessor;
|
||||||
|
import com.intellij.ui.components.JBCheckBox;
|
||||||
|
|
||||||
|
public interface ConfigurableAccessor<T> {
|
||||||
|
T get();
|
||||||
|
void set(Object value);
|
||||||
|
|
||||||
|
record TextFieldAccessor(TextAccessor accessor) implements ConfigurableAccessor<String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get() {
|
||||||
|
return accessor.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Object value) {
|
||||||
|
accessor.setText((String)value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
record CheckBoxAccessor(JBCheckBox checkBox) implements ConfigurableAccessor<Boolean> {
|
||||||
|
@Override
|
||||||
|
public Boolean get() {
|
||||||
|
return checkBox.isSelected() == Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Object value) {
|
||||||
|
checkBox.setSelected(value == Boolean.TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.Category;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.Config;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.FilePath;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.Label;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.Separator;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.VerticalGap;
|
||||||
|
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||||
|
import com.intellij.openapi.ui.TextBrowseFolderListener;
|
||||||
|
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||||
|
import com.intellij.ui.TextAccessor;
|
||||||
|
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 javax.swing.JComponent;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.VarHandle;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ConfigurableGui<T> {
|
||||||
|
private final JPanel thePanel;
|
||||||
|
|
||||||
|
private final Map<String, ConfigurableAccessor<?>> guiProps;
|
||||||
|
private final Map<String, VarHandle> configProps;
|
||||||
|
private final Set<String> props;
|
||||||
|
private ConfigurableGui(JPanel thePanel,
|
||||||
|
Map<String, ConfigurableAccessor<?>> guiProps,
|
||||||
|
Map<String, VarHandle> configProps,
|
||||||
|
Set<String> props) {
|
||||||
|
this.thePanel = thePanel;
|
||||||
|
this.guiProps = guiProps;
|
||||||
|
this.configProps = configProps;
|
||||||
|
this.props = props;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JPanel getPanel() {
|
||||||
|
return thePanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean modified(T holder) {
|
||||||
|
return modified(holder, false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean modified(T holder, boolean exclude, Set<String> mask) {
|
||||||
|
for (var prop: props) {
|
||||||
|
if (mask != null && mask.contains(prop) == exclude) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(guiProps.get(prop).get(), configProps.get(prop).get(holder))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void guiToConfig(T holder) {
|
||||||
|
for (var prop: props) {
|
||||||
|
configProps.get(prop).set(holder, guiProps.get(prop).get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configToGui(T holder) {
|
||||||
|
for (var prop: props) {
|
||||||
|
guiProps.get(prop).set(configProps.get(prop).get(holder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Supplier<ConfigurableGui<T>> create(MethodHandles.Lookup lookup, Class<T> dataContainer)
|
||||||
|
throws IllegalAccessException {
|
||||||
|
var fields = Arrays.stream(dataContainer.getFields())
|
||||||
|
.filter(field -> field.isAnnotationPresent(Config.class))
|
||||||
|
.filter(field -> field.isAnnotationPresent(Label.class))
|
||||||
|
.sorted(Comparator.comparingInt(field -> field.getAnnotation(Config.class).value()))
|
||||||
|
.toList();
|
||||||
|
var configProps = new HashMap<String, VarHandle>();
|
||||||
|
var props = new HashSet<String>();
|
||||||
|
var steps = new ArrayList<BiConsumer<HashMap<String, ConfigurableAccessor<?>>, FormBuilder>>();
|
||||||
|
for (var field: fields) {
|
||||||
|
var propName = field.getName();
|
||||||
|
var fieldType = field.getType();
|
||||||
|
var label = field.getAnnotation(Label.class).value();
|
||||||
|
if (field.isAnnotationPresent(VerticalGap.class)) {
|
||||||
|
var gap = field.getAnnotation(VerticalGap.class).value();
|
||||||
|
steps.add((gp, fb) -> fb.addVerticalGap(gap));
|
||||||
|
}
|
||||||
|
if (field.isAnnotationPresent(Separator.class)) {
|
||||||
|
steps.add((gp, fb) -> fb.addSeparator());
|
||||||
|
}
|
||||||
|
if (field.isAnnotationPresent(Category.class)) {
|
||||||
|
var cat = field.getAnnotation(Category.class).value();
|
||||||
|
steps.add((gp, fb) -> fb.addSeparator()
|
||||||
|
.addComponent(new JBLabel(cat))
|
||||||
|
.addVerticalGap(10));
|
||||||
|
}
|
||||||
|
Function<HashMap<String, ConfigurableAccessor<?>>, JComponent> component;
|
||||||
|
if (fieldType.equals(String.class)) {
|
||||||
|
var isFilePath = field.isAnnotationPresent(FilePath.class);
|
||||||
|
if (isFilePath) {
|
||||||
|
var filePathSpec = field.getAnnotation(FilePath.class);
|
||||||
|
var descriptor = new FileChooserDescriptor(filePathSpec.files(),
|
||||||
|
filePathSpec.folders(),
|
||||||
|
filePathSpec.jars(),
|
||||||
|
filePathSpec.jarsAsFiles(),
|
||||||
|
filePathSpec.jarContents(),
|
||||||
|
filePathSpec.multiple());
|
||||||
|
component = (guiProps) -> {
|
||||||
|
var theComponent = new TextFieldWithBrowseButton();
|
||||||
|
theComponent.addBrowseFolderListener(new TextBrowseFolderListener(descriptor));
|
||||||
|
guiProps.put(propName, new ConfigurableAccessor.TextFieldAccessor(theComponent));
|
||||||
|
return theComponent;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
component = (guiProps) -> {
|
||||||
|
var theComponent = new JBTextField();
|
||||||
|
guiProps.put(propName, new ConfigurableAccessor.TextFieldAccessor(theComponent));
|
||||||
|
return theComponent;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (fieldType.equals(boolean.class)) {
|
||||||
|
component = (guiProps) -> {
|
||||||
|
var theComponent = new JBCheckBox();
|
||||||
|
guiProps.put(propName, new ConfigurableAccessor.CheckBoxAccessor(theComponent));
|
||||||
|
return theComponent;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
component = null;
|
||||||
|
}
|
||||||
|
if (component != null) {
|
||||||
|
props.add(propName);
|
||||||
|
configProps.put(propName, lookup.unreflectVarHandle(field));
|
||||||
|
}
|
||||||
|
steps.add((gp, fb) -> {
|
||||||
|
var comp = component == null ? null : component.apply(gp);
|
||||||
|
if (comp != null) {
|
||||||
|
fb.addLabeledComponent(new JBLabel(label), comp, 1, false);
|
||||||
|
} else {
|
||||||
|
fb.addComponent(new JBLabel(label));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
steps.add((gp, fb) -> fb.addComponentFillVertically(new JPanel(), 0));
|
||||||
|
|
||||||
|
return () -> {
|
||||||
|
var gp = new HashMap<String, ConfigurableAccessor<?>>();
|
||||||
|
var fb = FormBuilder.createFormBuilder();
|
||||||
|
for (var step: steps) {
|
||||||
|
step.accept(gp, fb);
|
||||||
|
}
|
||||||
|
for (var prop: props) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return new ConfigurableGui<>(fb.getPanel(), gp, configProps, props);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Category {
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Config {
|
||||||
|
int value();
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface FilePath {
|
||||||
|
boolean files() default false;
|
||||||
|
boolean folders() default false;
|
||||||
|
boolean jars() default false;
|
||||||
|
boolean jarsAsFiles() default false;
|
||||||
|
boolean jarContents() default false;
|
||||||
|
boolean multiple() default false;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Label {
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Separator {
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface VerticalGap {
|
||||||
|
int value();
|
||||||
|
}
|
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.zig.ide;
|
package com.falsepattern.zigbrains.zig.ide;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.zig.settings.AppSettingsState;
|
import com.falsepattern.zigbrains.zig.settings.ZLSSettingsState;
|
||||||
|
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;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -40,7 +41,7 @@ public class ZigFoldingRangeProvider extends LSPFoldingRangeProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean async() {
|
protected boolean async(Project project) {
|
||||||
return AppSettingsState.getInstance().asyncFolding;
|
return ZLSSettingsState.getInstance(project).asyncFolding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.zig.lsp;
|
package com.falsepattern.zigbrains.zig.lsp;
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.zig.settings.AppSettingsState;
|
import com.falsepattern.zigbrains.lsp.utils.FileUtils;
|
||||||
|
import com.falsepattern.zigbrains.zig.settings.ZLSSettingsState;
|
||||||
import com.intellij.notification.Notification;
|
import com.intellij.notification.Notification;
|
||||||
import com.intellij.notification.NotificationType;
|
import com.intellij.notification.NotificationType;
|
||||||
import com.intellij.notification.Notifications;
|
import com.intellij.notification.Notifications;
|
||||||
|
@ -38,11 +39,19 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
public class ZLSStartupActivity implements ProjectActivity {
|
public class ZLSStartupActivity implements ProjectActivity {
|
||||||
private static final ReentrantLock lock = new ReentrantLock();
|
private static final ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
public static void initZLS() {
|
public static void initZLS(Project project) {
|
||||||
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
var settings = AppSettingsState.getInstance();
|
var wrappers = IntellijLanguageClient.getAllServerWrappersFor(FileUtils.projectToUri(project));
|
||||||
|
for (var wrapper : wrappers) {
|
||||||
|
if (wrapper.serverDefinition.ext.equals("zig")) {
|
||||||
|
wrapper.stop(false);
|
||||||
|
wrapper.stop(true);
|
||||||
|
IntellijLanguageClient.removeWrapper(wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var settings = ZLSSettingsState.getInstance(project);
|
||||||
var zlsPath = settings.zlsPath;
|
var zlsPath = settings.zlsPath;
|
||||||
if (!validatePath("ZLS Binary", zlsPath, false)) {
|
if (!validatePath("ZLS Binary", zlsPath, false)) {
|
||||||
return;
|
return;
|
||||||
|
@ -90,7 +99,7 @@ public class ZLSStartupActivity implements ProjectActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IntellijLanguageClient.addServerDefinition(new ZLSServerDefinition(cmd.toArray(String[]::new)));
|
IntellijLanguageClient.addServerDefinition(new ZLSServerDefinition(cmd.toArray(String[]::new)), project);
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
@ -127,14 +136,14 @@ 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 path = AppSettingsState.getInstance().zlsPath;
|
var path = ZLSSettingsState.getInstance(project).zlsPath;
|
||||||
if ("".equals(path)) {
|
if ("".equals(path)) {
|
||||||
Notifications.Bus.notify(new Notification("ZigBrains.Nag", "No ZLS binary",
|
Notifications.Bus.notify(new Notification("ZigBrains.Nag", "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!",
|
||||||
NotificationType.INFORMATION));
|
NotificationType.INFORMATION));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
initZLS();
|
initZLS(project);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2023 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.util.ui.FormBuilder;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
public class AppSettingsComponent {
|
|
||||||
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 debugCheckBox = new JBCheckBox();
|
|
||||||
private final JBCheckBox messageTraceCheckBox = new JBCheckBox();
|
|
||||||
private final JBCheckBox increaseTimeouts = new JBCheckBox();
|
|
||||||
|
|
||||||
public AppSettingsComponent() {
|
|
||||||
zlsPathText.addBrowseFolderListener(
|
|
||||||
new TextBrowseFolderListener(new FileChooserDescriptor(true, false, false, false, false, false)));
|
|
||||||
myMainPanel = FormBuilder.createFormBuilder()
|
|
||||||
.addComponent(new JBLabel("Regular settings"))
|
|
||||||
.addVerticalGap(10)
|
|
||||||
.addLabeledComponent(new JBLabel("ZLS path: "), zlsPathText, 1, false)
|
|
||||||
.addLabeledComponent(new JBLabel("ZLS config path (leave empty to use default): "),
|
|
||||||
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(
|
|
||||||
"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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2023 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.zig.lsp.ZLSStartupActivity;
|
|
||||||
import com.intellij.openapi.options.Configurable;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
|
|
||||||
public class AppSettingsConfigurable implements Configurable {
|
|
||||||
private AppSettingsComponent appSettingsComponent;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDisplayName() {
|
|
||||||
return "Zig";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable JComponent createComponent() {
|
|
||||||
appSettingsComponent = new AppSettingsComponent();
|
|
||||||
return appSettingsComponent.getPanel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isModified() {
|
|
||||||
var settings = AppSettingsState.getInstance();
|
|
||||||
boolean modified = zlsSettingsModified(settings);
|
|
||||||
modified |= settings.asyncFolding != appSettingsComponent.getAsyncFolding();
|
|
||||||
return modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean zlsSettingsModified(AppSettingsState 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();
|
|
||||||
return modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void apply() {
|
|
||||||
var settings = AppSettingsState.getInstance();
|
|
||||||
boolean reloadZLS = zlsSettingsModified(settings);
|
|
||||||
settings.zlsPath = appSettingsComponent.getZLSPath();
|
|
||||||
settings.zlsConfigPath = appSettingsComponent.getZLSConfigPath();
|
|
||||||
settings.asyncFolding = appSettingsComponent.getAsyncFolding();
|
|
||||||
settings.debug = appSettingsComponent.getDebug();
|
|
||||||
settings.messageTrace = appSettingsComponent.getMessageTrace();
|
|
||||||
settings.increaseTimeouts = appSettingsComponent.getIncreaseTimeouts();
|
|
||||||
if (reloadZLS) {
|
|
||||||
ZLSStartupActivity.initZLS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
var settings = AppSettingsState.getInstance();
|
|
||||||
appSettingsComponent.setZLSPath(settings.zlsPath);
|
|
||||||
appSettingsComponent.setZLSConfigPath(settings.zlsConfigPath);
|
|
||||||
appSettingsComponent.setDebug(settings.debug);
|
|
||||||
appSettingsComponent.setAsyncFolding(settings.asyncFolding);
|
|
||||||
appSettingsComponent.setMessageTrace(settings.messageTrace);
|
|
||||||
appSettingsComponent.setIncreaseTimeouts(settings.increaseTimeouts);
|
|
||||||
appSettingsComponent.setAsyncFolding(settings.asyncFolding);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disposeUIResources() {
|
|
||||||
appSettingsComponent = null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.settings.AbstractConfigurable;
|
||||||
|
import com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity;
|
||||||
|
import com.intellij.openapi.options.ConfigurationException;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ZLSSettingsConfigurable extends AbstractConfigurable<ZLSSettingsState> {
|
||||||
|
private static final MethodHandles.Lookup LOOKUP = MethodHandles.publicLookup();
|
||||||
|
|
||||||
|
private static final Set<String> RELOAD_CONFIGS = Set.of("zlsPath", "zlsConfigPath", "increaseTimeouts", "debug", "messageTrace");
|
||||||
|
|
||||||
|
private final Project project;
|
||||||
|
|
||||||
|
public ZLSSettingsConfigurable(@NotNull Project project) throws IllegalAccessException {
|
||||||
|
super(LOOKUP, "Zig", ZLSSettingsState.class);
|
||||||
|
this.project = project;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply() throws ConfigurationException {
|
||||||
|
boolean reloadZLS = zlsSettingsModified();
|
||||||
|
super.apply();
|
||||||
|
if (reloadZLS) {
|
||||||
|
ZLSStartupActivity.initZLS(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean zlsSettingsModified() {
|
||||||
|
if (configurableGui != null) {
|
||||||
|
return configurableGui.modified(getHolder(), false, RELOAD_CONFIGS);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ZLSSettingsState getHolder() {
|
||||||
|
return ZLSSettingsState.getInstance(project);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,36 +16,56 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.zig.settings;
|
package com.falsepattern.zigbrains.zig.settings;
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.falsepattern.zigbrains.settings.annotations.Category;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.Config;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.FilePath;
|
||||||
|
import com.falsepattern.zigbrains.settings.annotations.Label;
|
||||||
import com.intellij.openapi.components.PersistentStateComponent;
|
import com.intellij.openapi.components.PersistentStateComponent;
|
||||||
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.util.xmlb.XmlSerializerUtil;
|
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@Service(Service.Level.APP)
|
@Service(Service.Level.PROJECT)
|
||||||
@State(name = "com.falsepattern.zigbrains.zig.settings.AppSettingsState",
|
@State(name = "ZLSSettings",
|
||||||
storages = @Storage("ZigBrainsSettings.xml"))
|
storages = @Storage("zigbrains.xml"))
|
||||||
public final class AppSettingsState implements PersistentStateComponent<AppSettingsState> {
|
public final class ZLSSettingsState implements PersistentStateComponent<ZLSSettingsState> {
|
||||||
|
@Category("Regular settings")
|
||||||
|
@Config(0)
|
||||||
|
@Label("ZLS path: ")
|
||||||
|
@FilePath(files = true)
|
||||||
public String zlsPath = "";
|
public String zlsPath = "";
|
||||||
|
@Config(10)
|
||||||
|
@Label("ZLS config path (leave empty to use default): ")
|
||||||
|
@FilePath(files = true)
|
||||||
public String zlsConfigPath = "";
|
public String zlsConfigPath = "";
|
||||||
public boolean debug = false;
|
@Config(20)
|
||||||
public boolean asyncFolding = true;
|
@Label("Increase timeouts")
|
||||||
public boolean messageTrace = false;
|
|
||||||
public boolean increaseTimeouts = false;
|
public boolean increaseTimeouts = false;
|
||||||
|
@Config(30)
|
||||||
|
@Label("Asynchronous code folding ranges: ")
|
||||||
|
public boolean asyncFolding = true;
|
||||||
|
@Category("Developer settings (only usable when the IDE was launched with the runIDE gradle task in ZigBrains!)")
|
||||||
|
@Config(40)
|
||||||
|
@Label("ZLS debug log: ")
|
||||||
|
public boolean debug = false;
|
||||||
|
@Config(50)
|
||||||
|
@Label("ZLS message trace: ")
|
||||||
|
public boolean messageTrace = false;
|
||||||
|
|
||||||
public static AppSettingsState getInstance() {
|
public static ZLSSettingsState getInstance(Project project) {
|
||||||
return ApplicationManager.getApplication().getService(AppSettingsState.class);
|
return project.getService(ZLSSettingsState.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppSettingsState getState() {
|
public ZLSSettingsState getState() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadState(@NotNull AppSettingsState state) {
|
public void loadState(@NotNull ZLSSettingsState state) {
|
||||||
XmlSerializerUtil.copyBean(state, this);
|
XmlSerializerUtil.copyBean(state, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -86,10 +86,10 @@
|
||||||
<lang.braceMatcher language="Zig"
|
<lang.braceMatcher language="Zig"
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.pairing.ZigBraceMatcher"/>
|
implementationClass="com.falsepattern.zigbrains.zig.pairing.ZigBraceMatcher"/>
|
||||||
|
|
||||||
<applicationConfigurable parentId="language"
|
<projectConfigurable parentId="language"
|
||||||
instance="com.falsepattern.zigbrains.zig.settings.AppSettingsConfigurable"
|
instance="com.falsepattern.zigbrains.zig.settings.ZLSSettingsConfigurable"
|
||||||
id="com.falsepattern.zigbrains.zig.settings.AppSettingsConfigurable"
|
id="com.falsepattern.zigbrains.zig.settings.ZLSSettingsConfigurable"
|
||||||
displayName="Zig"/>
|
displayName="Zig"/>
|
||||||
|
|
||||||
<postStartupActivity implementation="com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity"/>
|
<postStartupActivity implementation="com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity"/>
|
||||||
<notificationGroup displayType="BALLOON"
|
<notificationGroup displayType="BALLOON"
|
||||||
|
|
Loading…
Add table
Reference in a new issue