use the new workspace symbol location prefix search capability in symbols in project dialog mode
This commit is contained in:
@@ -10,45 +10,38 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.lsp4e.LSPEclipseUtils;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4j.DocumentSymbol;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.handlers.HandlerUtil;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin;
|
||||
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class InProjectSymbolsProvider extends InWorkspaceSymbolsProvider {
|
||||
public class InProjectSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
private final Predicate<? super Either<SymbolInformation, DocumentSymbol>> FILTER_PREDICATE = e -> {
|
||||
if(e.isLeft()) {
|
||||
SymbolInformation symbolInformation = e.getLeft();
|
||||
Location location = symbolInformation.getLocation();
|
||||
IResource targetResource = LSPEclipseUtils.findResourceFor(location.getUri());
|
||||
if (targetResource != null && targetResource.getFullPath() != null) {
|
||||
return targetResource.getFullPath().toString().startsWith("/" + getProject().getName() + "/");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
public InProjectSymbolsProvider(List<LanguageServer> languageServers, IProject project) {
|
||||
super(languageServers, project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Symbols in Project";
|
||||
}
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(ExecutionEvent event) {
|
||||
public static InProjectSymbolsProvider createFor(ExecutionEvent event) {
|
||||
final IProject project = InWorkspaceSymbolsProvider.projectFor(event);
|
||||
final List<LanguageServer> languageServers = LanguageServiceAccessor.getLanguageServers(project,
|
||||
capabilities -> Boolean.TRUE.equals(capabilities.getWorkspaceSymbolProvider()), true);
|
||||
@@ -58,9 +51,58 @@ public class InProjectSymbolsProvider extends InWorkspaceSymbolsProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Duration TIMEOUT = Duration.ofSeconds(2);
|
||||
private static final int MAX_RESULTS = 200;
|
||||
|
||||
private List<LanguageServer> languageServers;
|
||||
private IProject project;
|
||||
|
||||
public InProjectSymbolsProvider(List<LanguageServer> languageServers, IProject project) {
|
||||
this.languageServers = languageServers;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<? super Either<SymbolInformation, DocumentSymbol>> symbolFilter() {
|
||||
return FILTER_PREDICATE;
|
||||
public String getName() {
|
||||
return "Symbols in Project";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Either<SymbolInformation, DocumentSymbol>> fetchFor(String query) throws Exception {
|
||||
//TODO: if we want decent support for multiple language servers...
|
||||
// consider changing SymbolsProvider api and turning the stuff in here into something producing a
|
||||
// Flux<Collection<SymbolInformation>>
|
||||
// This will help in
|
||||
// - supporting cancelation
|
||||
// - executing multiple requests to different servers in parallel.
|
||||
// - producing results per server so don't have to wait for one slow server to see the rest.
|
||||
//However it will also add complexity to the code that consumes this and at this time we only
|
||||
// really use this with a single language server anyways.
|
||||
|
||||
String projectLocationPrefix = LSPEclipseUtils.toUri(project).toString();
|
||||
query = "locationPrefix:" + projectLocationPrefix + "?" + query;
|
||||
|
||||
WorkspaceSymbolParams params = new WorkspaceSymbolParams(query);
|
||||
|
||||
Flux<Either<SymbolInformation, DocumentSymbol>> symbols = Flux.fromIterable(this.languageServers)
|
||||
.flatMap(server -> Mono.fromFuture(server.getWorkspaceService().symbol(params))
|
||||
.timeout(TIMEOUT)
|
||||
.doOnError(e -> log(e))
|
||||
.onErrorReturn(ImmutableList.of())
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.map(symbol -> Either.forLeft(symbol))
|
||||
);
|
||||
//Consider letting the Flux go out from here instead of blocking and collecting elements.
|
||||
return symbols.take(MAX_RESULTS).collect(Collectors.toList()).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fromFile(SymbolInformation symbol) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void log(Throwable e) {
|
||||
GotoSymbolPlugin.getInstance().getLog().log(ExceptionUtil.status(e));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2019 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -12,7 +12,6 @@ package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
@@ -31,7 +30,6 @@ import org.eclipse.ui.handlers.HandlerUtil;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin;
|
||||
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -40,15 +38,23 @@ import reactor.core.publisher.Mono;
|
||||
@SuppressWarnings("restriction")
|
||||
public class InWorkspaceSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(IProject project) {
|
||||
List<LanguageServer> languageServers = LanguageServiceAccessor.getLanguageServers(project,
|
||||
capabilities -> Boolean.TRUE.equals(capabilities.getWorkspaceSymbolProvider()), true);
|
||||
if (!languageServers.isEmpty()) {
|
||||
return new InWorkspaceSymbolsProvider(languageServers);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static final Duration TIMEOUT = Duration.ofSeconds(2);
|
||||
private static final int MAX_RESULTS = 200;
|
||||
|
||||
private List<LanguageServer> languageServers;
|
||||
private IProject project;
|
||||
|
||||
public InWorkspaceSymbolsProvider(List<LanguageServer> languageServers, IProject project) {
|
||||
public InWorkspaceSymbolsProvider(List<LanguageServer> languageServers) {
|
||||
this.languageServers = languageServers;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,16 +84,12 @@ public class InWorkspaceSymbolsProvider implements SymbolsProvider {
|
||||
.map(symbol -> Either.forLeft(symbol))
|
||||
);
|
||||
//Consider letting the Flux go out from here instead of blocking and collecting elements.
|
||||
return symbols.filter(symbolFilter()).take(MAX_RESULTS).collect(Collectors.toList()).block();
|
||||
}
|
||||
|
||||
private static void log(Throwable e) {
|
||||
GotoSymbolPlugin.getInstance().getLog().log(ExceptionUtil.status(e));
|
||||
return symbols.take(MAX_RESULTS).collect(Collectors.toList()).block();
|
||||
}
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(ExecutionEvent event) {
|
||||
final IProject project = projectFor(event);
|
||||
if (project!=null) {
|
||||
if (project != null) {
|
||||
return createFor(project);
|
||||
}
|
||||
return null;
|
||||
@@ -113,26 +115,13 @@ public class InWorkspaceSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
}
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(IProject project) {
|
||||
List<LanguageServer> languageServers = LanguageServiceAccessor.getLanguageServers(project,
|
||||
capabilities -> Boolean.TRUE.equals(capabilities.getWorkspaceSymbolProvider()), true);
|
||||
if (!languageServers.isEmpty()) {
|
||||
return new InWorkspaceSymbolsProvider(languageServers, project);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fromFile(SymbolInformation symbol) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Predicate<? super Either<SymbolInformation, DocumentSymbol>> symbolFilter() {
|
||||
return Predicates.alwaysTrue();
|
||||
}
|
||||
|
||||
protected IProject getProject() {
|
||||
return project;
|
||||
private static void log(Throwable e) {
|
||||
GotoSymbolPlugin.getInstance().getLog().log(ExceptionUtil.status(e));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user