Skip to content

Commit 8622ecf

Browse files
committed
Implement selectionRange for Rascal.
1 parent 95ceb84 commit 8622ecf

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalTextDocumentService.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
import org.eclipse.lsp4j.RenameFilesParams;
7878
import org.eclipse.lsp4j.RenameOptions;
7979
import org.eclipse.lsp4j.RenameParams;
80+
import org.eclipse.lsp4j.SelectionRange;
81+
import org.eclipse.lsp4j.SelectionRangeParams;
8082
import org.eclipse.lsp4j.SemanticTokens;
8183
import org.eclipse.lsp4j.SemanticTokensDelta;
8284
import org.eclipse.lsp4j.SemanticTokensDeltaParams;
@@ -190,6 +192,7 @@ public void initializeServerCapabilities(ServerCapabilities result) {
190192
result.setRenameProvider(new RenameOptions(true));
191193
result.setCodeActionProvider(true);
192194
result.setExecuteCommandProvider(new ExecuteCommandOptions(Collections.singletonList(RascalWorkspaceService.RASCAL_COMMAND)));
195+
result.setSelectionRangeProvider(true);
193196
}
194197

195198
@Override
@@ -517,6 +520,36 @@ public CompletableFuture<SemanticTokens> semanticTokensRange(SemanticTokensRange
517520
return getSemanticTokens(params.getTextDocument());
518521
}
519522

523+
@Override
524+
public CompletableFuture<List<SelectionRange>> selectionRange(SelectionRangeParams params) {
525+
logger.debug("Selection range: {}", params);
526+
TextDocumentState file = getFile(params.getTextDocument());
527+
return file.getCurrentTreeAsync()
528+
.thenApply(Versioned::get)
529+
.handle((t, r) -> (t == null ? file.getLastTreeWithoutErrors().get() : t))
530+
.thenApply(tr -> params.getPositions().stream()
531+
.map(p -> {
532+
Position rascalCursorPos = Locations.toRascalPosition(file.getLocation(), p, columns);
533+
// Compute focus list for cursor position
534+
var focus = TreeSearch.computeFocusList(tr, rascalCursorPos.getLine(), rascalCursorPos.getCharacter());
535+
// Iterate in reverse order, starting with the outermost location
536+
var ranges = focus.reverse().stream()
537+
.map(ITree.class::cast)
538+
.map(TreeAdapter::getLocation)
539+
// Map to distinct ranges
540+
.map(l -> Locations.toRange(l, columns)).distinct()
541+
.collect(Collectors.toList());
542+
543+
// reduce to a single, nested SelectionRange
544+
SelectionRange parent = null;
545+
for (var r : ranges) {
546+
parent = new SelectionRange(r, parent);
547+
}
548+
return parent;
549+
})
550+
.collect(Collectors.toList()));
551+
}
552+
520553
@Override
521554
public void registerLanguage(LanguageParameter lang) {
522555
throw new UnsupportedOperationException("registering language is a feature of the language parametric server, not of the Rascal server");

0 commit comments

Comments
 (0)