feat: Inlay hint toggle and shrinking

This commit is contained in:
FalsePattern 2024-10-25 19:57:41 +02:00
parent 9d0f81bd8d
commit c7560ebeca
Signed by: falsepattern
GPG key ID: E930CDEC50C50E23
6 changed files with 84 additions and 15 deletions

View file

@ -22,6 +22,10 @@ Changelog structure reference:
- Zig
- Syntax highlighting for escape sequences in strings
- LSP
- Option to toggle inlay hints on/off
- Compacted error{...} blocks in inlay hints
### Fixed
- Zig

View file

@ -1,5 +1,8 @@
package com.falsepattern.zigbrains.zig.lsp;
import com.falsepattern.zigbrains.zig.settings.ZLSProjectSettingsService;
import com.falsepattern.zigbrains.zig.settings.ZLSSettings;
import com.falsepattern.zigbrains.zig.settings.ZLSSettingsConfigProvider;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LanguageServerEnablementSupport;
@ -7,7 +10,10 @@ import com.redhat.devtools.lsp4ij.LanguageServerFactory;
import com.redhat.devtools.lsp4ij.client.LanguageClientImpl;
import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures;
import com.redhat.devtools.lsp4ij.client.features.LSPFormattingFeature;
import com.redhat.devtools.lsp4ij.client.features.LSPInlayHintFeature;
import com.redhat.devtools.lsp4ij.server.StreamConnectionProvider;
import com.redhat.devtools.lsp4ij.server.capabilities.InlayHintCapabilityRegistry;
import lombok.val;
import org.jetbrains.annotations.NotNull;
public class ZLSLanguageServerFactory implements LanguageServerFactory, LanguageServerEnablementSupport {
@ -20,13 +26,20 @@ public class ZLSLanguageServerFactory implements LanguageServerFactory, Language
@SuppressWarnings("UnstableApiUsage")
@Override
public @NotNull LSPClientFeatures createClientFeatures() {
return new LSPClientFeatures()
.setFormattingFeature(new LSPFormattingFeature() {
@Override
protected boolean isExistingFormatterOverrideable(@NotNull PsiFile file) {
return true;
}
});
val features = new LSPClientFeatures();
features.setFormattingFeature(new LSPFormattingFeature() {
@Override
protected boolean isExistingFormatterOverrideable(@NotNull PsiFile file) {
return true;
}
});
features.setInlayHintFeature(new LSPInlayHintFeature() {
@Override
public boolean isEnabled(@NotNull PsiFile file) {
return ZLSProjectSettingsService.getInstance(features.getProject()).getState().inlayHints;
}
});
return features;
}
@Override

View file

@ -17,21 +17,29 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.redhat.devtools.lsp4ij.server.OSProcessStreamConnectionProvider;
import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider;
import lombok.val;
import org.eclipse.lsp4j.InlayHint;
import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
import org.eclipse.lsp4j.services.LanguageServer;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
public class ZLSStreamConnectionProvider extends OSProcessStreamConnectionProvider {
private static final Logger LOG = Logger.getInstance(ZLSStreamConnectionProvider.class);
private final Project project;
public ZLSStreamConnectionProvider(Project project) {
this.project = project;
val command = getCommand(project);
val projectDir = ProjectUtil.guessProjectDir(project);
GeneralCommandLine commandLine = null;
@ -50,6 +58,36 @@ public class ZLSStreamConnectionProvider extends OSProcessStreamConnectionProvid
setCommandLine(commandLine);
}
@Override
public void handleMessage(Message message, LanguageServer languageServer, VirtualFile rootUri) {
if (ZLSProjectSettingsService.getInstance(project).getState().inlayHintsCompact) {
if (message instanceof ResponseMessage resp) {
val res = resp.getResult();
if (res instanceof Collection<?> c) {
c.forEach(e -> {
if (e instanceof InlayHint ih) {
tryMutateInlayHint(ih);
}
});
} else if (res instanceof InlayHint ih) {
tryMutateInlayHint(ih);
}
}
}
super.handleMessage(message, languageServer, rootUri);
}
private static final Pattern ERROR_BLOCK = Pattern.compile("error\\{.*?}", Pattern.DOTALL);
private void tryMutateInlayHint(InlayHint inlayHint) {
if (inlayHint.getLabel().isLeft()) {
val str = inlayHint.getLabel().getLeft();
val shortened = ERROR_BLOCK.matcher(str).replaceAll("error{...}");
inlayHint.setLabel(shortened);
}
}
public static List<String> doGetCommand(Project project, boolean safe) {
var svc = ZLSProjectSettingsService.getInstance(project);
val state = svc.getState();

View file

@ -47,6 +47,8 @@ public final class ZLSProjectSettingsService extends WrappingStateComponent<ZLSS
modified |= !Objects.equals(myData.buildOnSaveStep, otherData.buildOnSaveStep);
modified |= myData.highlightGlobalVarDeclarations != otherData.highlightGlobalVarDeclarations;
modified |= myData.dangerousComptimeExperimentsDoNotEnable != otherData.dangerousComptimeExperimentsDoNotEnable;
modified |= myData.inlayHints != otherData.inlayHints;
modified |= myData.inlayHintsCompact != otherData.inlayHintsCompact;
return modified;
}
}

View file

@ -32,8 +32,10 @@ public final class ZLSSettings {
public @NotNull String buildOnSaveStep;
public boolean highlightGlobalVarDeclarations;
public boolean dangerousComptimeExperimentsDoNotEnable;
public boolean inlayHints;
public boolean inlayHintsCompact;
public ZLSSettings() {
this(null, "", false, false, false, "install", false, false);
this(null, "", false, false, false, "install", false, false, true, true);
}
}

View file

@ -47,6 +47,8 @@ public class ZLSSettingsPanel implements Disposable {
private final JBTextField buildOnSaveStep = new ExtendableTextField();
private final JBCheckBox highlightGlobalVarDeclarations = new JBCheckBox();
private final JBCheckBox dangerousComptimeExperimentsDoNotEnable = new JBCheckBox();
private final JBCheckBox inlayHints = new JBCheckBox();
private final JBCheckBox inlayHintsCompact = new JBCheckBox();
private final JBCheckBox messageTrace = new JBCheckBox();
private final JBCheckBox debug = new JBCheckBox();
@ -56,6 +58,8 @@ public class ZLSSettingsPanel implements Disposable {
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");
inlayHints.setToolTipText("Enable inlay hints");
inlayHintsCompact.setToolTipText("Replace extremely long error{...} snippets in inlay hints with a placeholder");
}
private void autodetect(ActionEvent e) {
@ -80,6 +84,8 @@ public class ZLSSettingsPanel implements Disposable {
r.button("Autodetect", $f(this::autodetect));
});
p.cell("Config path (leave empty to use built-in config)", zlsConfigPath, AlignX.FILL);
p.cell("Inlay hints", inlayHints);
p.cell("Compact errors in inlay hint", inlayHintsCompact);
p.cell("Build on save", buildOnSave);
p.row("Build on save step", r -> {
r.cell(buildOnSaveStep).resizableColumn().align(AlignX.FILL);
@ -95,13 +101,15 @@ public class ZLSSettingsPanel implements Disposable {
public ZLSSettings getData() {
return new ZLSSettings(zlsPath.getText(),
zlsConfigPath.getText(),
debug.isSelected(),
messageTrace.isSelected(),
buildOnSave.isSelected(),
buildOnSaveStep.getText(),
highlightGlobalVarDeclarations.isSelected(),
dangerousComptimeExperimentsDoNotEnable.isSelected());
zlsConfigPath.getText(),
debug.isSelected(),
messageTrace.isSelected(),
buildOnSave.isSelected(),
buildOnSaveStep.getText(),
highlightGlobalVarDeclarations.isSelected(),
dangerousComptimeExperimentsDoNotEnable.isSelected(),
inlayHints.isSelected(),
inlayHintsCompact.isSelected());
}
public void setData(ZLSSettings value) {
@ -113,6 +121,8 @@ public class ZLSSettingsPanel implements Disposable {
buildOnSaveStep.setText(value.buildOnSaveStep);
highlightGlobalVarDeclarations.setSelected(value.highlightGlobalVarDeclarations);
dangerousComptimeExperimentsDoNotEnable.setSelected(value.dangerousComptimeExperimentsDoNotEnable);
inlayHints.setSelected(value.inlayHints);
inlayHintsCompact.setSelected(value.inlayHintsCompact);
}
@Override