Skip to content

Commit 8c2ca32

Browse files
committed
feat: Inlay hints with text edits can be applied when clicking on them
1 parent 0a47315 commit 8c2ca32

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/operations/inlayhint/LSPLineContentCodeMiningTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
import org.eclipse.lsp4j.InlayHint;
3434
import org.eclipse.lsp4j.InlayHintLabelPart;
3535
import org.eclipse.lsp4j.Position;
36+
import org.eclipse.lsp4j.Range;
37+
import org.eclipse.lsp4j.TextEdit;
38+
import org.eclipse.lsp4j.jsonrpc.messages.Either;
3639
import org.eclipse.swt.SWT;
3740
import org.eclipse.swt.events.MouseEvent;
3841
import org.eclipse.swt.widgets.Display;
@@ -75,6 +78,25 @@ public void singleLabelPartCommand() throws Exception {
7578
assertEquals(MockLanguageServer.SUPPORTED_COMMAND_ID, executedCommand.getCommand());
7679
assertEquals(command.getArguments(), executedCommand.getArguments());
7780
}
81+
82+
@Test
83+
void inlayHintWithTextEdit() throws Exception {
84+
IFile file = TestUtils.createUniqueTestFile(project, "lspt", "x = [1, 2]");
85+
ITextViewer textViewer = TestUtils.openTextViewer(file);
86+
IDocument document = textViewer.getDocument();
87+
88+
final var provider = new InlayHintProvider();
89+
90+
InlayHint inlayHint = new InlayHint(new Position(0,0), Either.forLeft(": list[int]"));
91+
inlayHint.setTextEdits(List.of(new TextEdit(new Range(new Position(0, 1),new Position(0,1)), ": list[int]")));
92+
93+
LanguageServerWrapper wrapper = LanguageServiceAccessor.getLSWrapper(project, LanguageServersRegistry.getInstance().getDefinition(MOCK_SERVER_ID));
94+
final var sut = new LSPLineContentCodeMining(inlayHint, document, wrapper, provider);
95+
MouseEvent mouseEvent = createMouseEvent();
96+
sut.getAction().accept(mouseEvent);
97+
98+
assertEquals(document.get(), "x: list[int] = [1, 2]");
99+
}
78100

79101
private static InlayHintLabelPart createInlayLabelPart(String text, String commandID) {
80102
final var labelPart = new InlayHintLabelPart(text);

org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/inlayhint/LSPLineContentCodeMining.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private static boolean canResolveInlayHint(@Nullable ServerCapabilities capabili
111111
Either<Boolean, InlayHintRegistrationOptions> inlayProvider = capabilities.getInlayHintProvider();
112112
if (inlayProvider != null && inlayProvider.isRight()) {
113113
InlayHintRegistrationOptions options = inlayProvider.getRight();
114-
return options.getResolveProvider() != null && options.getResolveProvider().booleanValue();
114+
return Boolean.TRUE.equals(options.getResolveProvider());
115115
}
116116
return false;
117117
}
@@ -134,7 +134,28 @@ private static org.eclipse.jface.text.Position toPosition(Position position, IDo
134134

135135
@Override
136136
public final @Nullable Consumer<MouseEvent> getAction() {
137-
return inlayHint.getLabel().map(l -> null, this::labelPartAction);
137+
// Check if there is a specific command to execute for the clicked on label part
138+
var consumer = inlayHint.getLabel().map(l -> null, this::labelPartAction);
139+
if (consumer != null) {
140+
return consumer;
141+
}
142+
143+
// Check if there are text edits to apply when clicking on the inlay hint
144+
if (inlayHint.getTextEdits() != null && !inlayHint.getTextEdits().isEmpty()) {
145+
return evt -> {
146+
try {
147+
LSPEclipseUtils.applyEdits(document, inlayHint.getTextEdits());
148+
// The text of the inlay hint is integrated into the document.
149+
// To avoid a brief moment where both the inserted text and the inlay hint are
150+
// rendered, we set an empty label for the hint.
151+
setLabel(""); //$NON-NLS-1$
152+
} catch (BadLocationException e) {
153+
// Location to modify document was no longer valid -> Ignore
154+
}
155+
};
156+
}
157+
158+
return null;
138159
}
139160

140161
private @Nullable Consumer<MouseEvent> labelPartAction(List<InlayHintLabelPart> labelParts) {

0 commit comments

Comments
 (0)