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 - Zig
- Syntax highlighting for escape sequences in strings - Syntax highlighting for escape sequences in strings
- LSP
- Option to toggle inlay hints on/off
- Compacted error{...} blocks in inlay hints
### Fixed ### Fixed
- Zig - Zig

View file

@ -1,5 +1,8 @@
package com.falsepattern.zigbrains.zig.lsp; 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.openapi.project.Project;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LanguageServerEnablementSupport; 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.LanguageClientImpl;
import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures; import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures;
import com.redhat.devtools.lsp4ij.client.features.LSPFormattingFeature; 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.StreamConnectionProvider;
import com.redhat.devtools.lsp4ij.server.capabilities.InlayHintCapabilityRegistry;
import lombok.val;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ZLSLanguageServerFactory implements LanguageServerFactory, LanguageServerEnablementSupport { public class ZLSLanguageServerFactory implements LanguageServerFactory, LanguageServerEnablementSupport {
@ -20,13 +26,20 @@ public class ZLSLanguageServerFactory implements LanguageServerFactory, Language
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
@Override @Override
public @NotNull LSPClientFeatures createClientFeatures() { public @NotNull LSPClientFeatures createClientFeatures() {
return new LSPClientFeatures() val features = new LSPClientFeatures();
.setFormattingFeature(new LSPFormattingFeature() { features.setFormattingFeature(new LSPFormattingFeature() {
@Override @Override
protected boolean isExistingFormatterOverrideable(@NotNull PsiFile file) { protected boolean isExistingFormatterOverrideable(@NotNull PsiFile file) {
return true; return true;
} }
}); });
features.setInlayHintFeature(new LSPInlayHintFeature() {
@Override
public boolean isEnabled(@NotNull PsiFile file) {
return ZLSProjectSettingsService.getInstance(features.getProject()).getState().inlayHints;
}
});
return features;
} }
@Override @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.OSProcessStreamConnectionProvider;
import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider; import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider;
import lombok.val; 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.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.InvalidPathException; import java.nio.file.InvalidPathException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.regex.Pattern;
public class ZLSStreamConnectionProvider extends OSProcessStreamConnectionProvider { public class ZLSStreamConnectionProvider extends OSProcessStreamConnectionProvider {
private static final Logger LOG = Logger.getInstance(ZLSStreamConnectionProvider.class); private static final Logger LOG = Logger.getInstance(ZLSStreamConnectionProvider.class);
private final Project project;
public ZLSStreamConnectionProvider(Project project) { public ZLSStreamConnectionProvider(Project project) {
this.project = project;
val command = getCommand(project); val command = getCommand(project);
val projectDir = ProjectUtil.guessProjectDir(project); val projectDir = ProjectUtil.guessProjectDir(project);
GeneralCommandLine commandLine = null; GeneralCommandLine commandLine = null;
@ -50,6 +58,36 @@ public class ZLSStreamConnectionProvider extends OSProcessStreamConnectionProvid
setCommandLine(commandLine); 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) { public static List<String> doGetCommand(Project project, boolean safe) {
var svc = ZLSProjectSettingsService.getInstance(project); var svc = ZLSProjectSettingsService.getInstance(project);
val state = svc.getState(); 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 |= !Objects.equals(myData.buildOnSaveStep, otherData.buildOnSaveStep);
modified |= myData.highlightGlobalVarDeclarations != otherData.highlightGlobalVarDeclarations; modified |= myData.highlightGlobalVarDeclarations != otherData.highlightGlobalVarDeclarations;
modified |= myData.dangerousComptimeExperimentsDoNotEnable != otherData.dangerousComptimeExperimentsDoNotEnable; modified |= myData.dangerousComptimeExperimentsDoNotEnable != otherData.dangerousComptimeExperimentsDoNotEnable;
modified |= myData.inlayHints != otherData.inlayHints;
modified |= myData.inlayHintsCompact != otherData.inlayHintsCompact;
return modified; return modified;
} }
} }

View file

@ -32,8 +32,10 @@ public final class ZLSSettings {
public @NotNull String buildOnSaveStep; public @NotNull String buildOnSaveStep;
public boolean highlightGlobalVarDeclarations; public boolean highlightGlobalVarDeclarations;
public boolean dangerousComptimeExperimentsDoNotEnable; public boolean dangerousComptimeExperimentsDoNotEnable;
public boolean inlayHints;
public boolean inlayHintsCompact;
public ZLSSettings() { 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 JBTextField buildOnSaveStep = new ExtendableTextField();
private final JBCheckBox highlightGlobalVarDeclarations = new JBCheckBox(); private final JBCheckBox highlightGlobalVarDeclarations = new JBCheckBox();
private final JBCheckBox dangerousComptimeExperimentsDoNotEnable = 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 messageTrace = new JBCheckBox();
private final JBCheckBox debug = 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"); buildOnSaveStep.setToolTipText("Select which step should be executed on build-on-save");
highlightGlobalVarDeclarations.setToolTipText("Whether to highlight global var declarations"); highlightGlobalVarDeclarations.setToolTipText("Whether to highlight global var declarations");
dangerousComptimeExperimentsDoNotEnable.setToolTipText("Whether to use the comptime interpreter"); 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) { private void autodetect(ActionEvent e) {
@ -80,6 +84,8 @@ public class ZLSSettingsPanel implements Disposable {
r.button("Autodetect", $f(this::autodetect)); r.button("Autodetect", $f(this::autodetect));
}); });
p.cell("Config path (leave empty to use built-in config)", zlsConfigPath, AlignX.FILL); 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.cell("Build on save", buildOnSave);
p.row("Build on save step", r -> { p.row("Build on save step", r -> {
r.cell(buildOnSaveStep).resizableColumn().align(AlignX.FILL); r.cell(buildOnSaveStep).resizableColumn().align(AlignX.FILL);
@ -101,7 +107,9 @@ public class ZLSSettingsPanel implements Disposable {
buildOnSave.isSelected(), buildOnSave.isSelected(),
buildOnSaveStep.getText(), buildOnSaveStep.getText(),
highlightGlobalVarDeclarations.isSelected(), highlightGlobalVarDeclarations.isSelected(),
dangerousComptimeExperimentsDoNotEnable.isSelected()); dangerousComptimeExperimentsDoNotEnable.isSelected(),
inlayHints.isSelected(),
inlayHintsCompact.isSelected());
} }
public void setData(ZLSSettings value) { public void setData(ZLSSettings value) {
@ -113,6 +121,8 @@ public class ZLSSettingsPanel implements Disposable {
buildOnSaveStep.setText(value.buildOnSaveStep); buildOnSaveStep.setText(value.buildOnSaveStep);
highlightGlobalVarDeclarations.setSelected(value.highlightGlobalVarDeclarations); highlightGlobalVarDeclarations.setSelected(value.highlightGlobalVarDeclarations);
dangerousComptimeExperimentsDoNotEnable.setSelected(value.dangerousComptimeExperimentsDoNotEnable); dangerousComptimeExperimentsDoNotEnable.setSelected(value.dangerousComptimeExperimentsDoNotEnable);
inlayHints.setSelected(value.inlayHints);
inlayHintsCompact.setSelected(value.inlayHintsCompact);
} }
@Override @Override