use of org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition in project lsp4e by eclipse.
the class LSPCodeActionMarkerResolution method checkMarkerResoultion.
private void checkMarkerResoultion(IMarker marker) throws IOException, CoreException, InterruptedException, ExecutionException, TimeoutException {
if (marker.getAttribute(LSP_REMEDIATION) == null) {
IResource res = marker.getResource();
if (res != null && res.getType() == IResource.FILE) {
IFile file = (IFile) res;
String languageServerId = marker.getAttribute(LSPDiagnosticsToMarkers.LANGUAGE_SERVER_ID, null);
List<CompletableFuture<LanguageServer>> languageServerFutures = new ArrayList<>();
if (languageServerId != null) {
// try to use same LS as the one that created the marker
LanguageServerDefinition definition = LanguageServersRegistry.getInstance().getDefinition(languageServerId);
if (definition != null) {
CompletableFuture<LanguageServer> serverFuture = LanguageServiceAccessor.getInitializedLanguageServer(file, definition, serverCapabilities -> serverCapabilities == null || providesCodeActions(serverCapabilities));
if (serverFuture != null) {
languageServerFutures.add(serverFuture);
}
}
}
if (languageServerFutures.isEmpty()) {
// if it's not there, try any other server
languageServerFutures.addAll(LanguageServiceAccessor.getInitializedLanguageServers(file, capabilities -> {
Either<Boolean, CodeActionOptions> codeActionProvider = capabilities.getCodeActionProvider();
if (codeActionProvider == null) {
return false;
} else if (codeActionProvider.isLeft()) {
return Boolean.TRUE.equals(codeActionProvider.getLeft());
} else if (codeActionProvider.isRight()) {
return true;
}
return false;
}));
}
List<CompletableFuture<?>> futures = new ArrayList<>();
for (CompletableFuture<LanguageServer> lsf : languageServerFutures) {
marker.setAttribute(LSP_REMEDIATION, COMPUTING);
Diagnostic diagnostic = (Diagnostic) marker.getAttribute(MarkerAttributeComputer.LSP_DIAGNOSTIC);
CodeActionContext context = new CodeActionContext(Collections.singletonList(diagnostic));
CodeActionParams params = new CodeActionParams();
params.setContext(context);
params.setTextDocument(new TextDocumentIdentifier(LSPEclipseUtils.toUri(marker.getResource()).toString()));
params.setRange(diagnostic.getRange());
CompletableFuture<List<Either<Command, CodeAction>>> codeAction = lsf.thenComposeAsync(ls -> ls.getTextDocumentService().codeAction(params));
futures.add(codeAction);
codeAction.thenAcceptAsync(actions -> {
try {
marker.setAttribute(LSP_REMEDIATION, actions);
} catch (CoreException e) {
LanguageServerPlugin.logError(e);
}
});
}
// wait a bit to avoid showing too much "Computing" without looking like a freeze
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).get(300, TimeUnit.MILLISECONDS);
}
}
}
use of org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition in project lsp4e by eclipse.
the class CommandExecutor method executeCommandServerSide.
private static CompletableFuture<Object> executeCommandServerSide(@NonNull Command command, @Nullable String languageServerId, @Nullable IDocument document) {
@Nullable LanguageServerDefinition languageServerDefinition = languageServerId == null ? null : LanguageServersRegistry.getInstance().getDefinition(languageServerId);
try {
CompletableFuture<LanguageServer> languageServerFuture = getLanguageServerForCommand(command, document, languageServerDefinition);
if (languageServerFuture == null) {
return null;
}
// Server can handle command
return languageServerFuture.thenApplyAsync(server -> {
ExecuteCommandParams params = new ExecuteCommandParams();
params.setCommand(command.getCommand());
params.setArguments(command.getArguments());
return server.getWorkspaceService().executeCommand(params);
});
} catch (IOException e) {
// log and let the code fall through for LSPEclipseUtils to handle
LanguageServerPlugin.logError(e);
return null;
}
}
use of org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition in project lsp4e by eclipse.
the class IncompleteCompletionTest method testAssistForUnknownButConnectedType.
/*
* This tests the not-so-official way to associate a LS to a file programmatically, and then to retrieve the LS
* for the file independently of the content-types. Although doing it programatically isn't recommended, consuming
* file-specific LS already associated is something we want to support.
*/
@Test
public void testAssistForUnknownButConnectedType() throws CoreException, InvocationTargetException, IOException, InterruptedException {
List<CompletionItem> items = new ArrayList<>();
items.add(createCompletionItem("FirstClass", CompletionItemKind.Class));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(true, items));
IFile testFile = TestUtils.createUniqueTestFileOfUnknownType(project, "");
ITextViewer viewer = TestUtils.openTextViewer(testFile);
LanguageServerDefinition serverDefinition = LanguageServersRegistry.getInstance().getDefinition("org.eclipse.lsp4e.test.server");
assertNotNull(serverDefinition);
LanguageServerWrapper lsWrapperForConnection = LanguageServiceAccessor.getLSWrapperForConnection(testFile.getProject(), serverDefinition);
URI fileLocation = testFile.getLocationURI();
// force connection (that's what LSP4E should be designed to prevent 3rd party from having to use it).
lsWrapperForConnection.connect(testFile, null);
new DisplayHelper() {
@Override
protected boolean condition() {
return lsWrapperForConnection.isConnectedTo(fileLocation);
}
}.waitForCondition(Display.getCurrent(), 3000);
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, 0);
assertEquals(items.size(), proposals.length);
// TODO compare both structures
LSCompletionProposal LSIncompleteCompletionProposal = (LSCompletionProposal) proposals[0];
LSIncompleteCompletionProposal.apply(viewer.getDocument());
assertEquals(new Point("FirstClass".length(), 0), LSIncompleteCompletionProposal.getSelection(viewer.getDocument()));
}
use of org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition in project jbosstools-quarkus by jbosstools.
the class SchemaRegistry method sendInitialize.
private void sendInitialize() {
List<LanguageServer> servers = LanguageServiceAccessor.getLanguageServers(null, null, true);
for (LanguageServer server : servers) {
Optional<LanguageServerDefinition> definition = LanguageServiceAccessor.resolveServerDefinition(server);
if (definition.isPresent()) {
if ("org.eclipse.wildwebdeveloper.yaml".equals(definition.get().id)) {
Map<String, Object> prefs = new HashMap<>();
prefs.put("schemas", schemas2YAMLLSMap());
prefs.put("completion", true);
prefs.put("hover", true);
prefs.put("validate", true);
DidChangeConfigurationParams params = new DidChangeConfigurationParams(Collections.singletonMap("yaml", prefs));
server.getWorkspaceService().didChangeConfiguration(params);
}
}
}
}
use of org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition in project lsp4e by eclipse.
the class LanguageServiceAccessor method getLSWrappers.
@NonNull
private static Collection<LanguageServerWrapper> getLSWrappers(@NonNull IDocument document) {
LinkedHashSet<LanguageServerWrapper> res = new LinkedHashSet<>();
IFile file = LSPEclipseUtils.getFile(document);
URI uri = LSPEclipseUtils.toUri(document);
if (uri == null) {
return Collections.emptyList();
}
IPath path = new Path(uri.getPath());
// look for running language servers via content-type
Queue<IContentType> contentTypes = new LinkedList<>();
Set<IContentType> processedContentTypes = new HashSet<>();
contentTypes.addAll(LSPEclipseUtils.getDocumentContentTypes(document));
synchronized (startedServers) {
// already started compatible servers that fit request
res.addAll(startedServers.stream().filter(wrapper -> {
try {
return wrapper.isConnectedTo(uri) || LanguageServersRegistry.getInstance().matches(document, wrapper.serverDefinition);
} catch (Exception e) {
LanguageServerPlugin.logError(e);
return false;
}
}).filter(wrapper -> wrapper.canOperate(document)).collect(Collectors.toList()));
while (!contentTypes.isEmpty()) {
IContentType contentType = contentTypes.poll();
if (contentType == null || processedContentTypes.contains(contentType)) {
continue;
}
for (ContentTypeToLanguageServerDefinition mapping : LanguageServersRegistry.getInstance().findProviderFor(contentType)) {
if (mapping == null || !mapping.isEnabled()) {
continue;
}
LanguageServerDefinition serverDefinition = mapping.getValue();
if (serverDefinition == null) {
continue;
}
if (startedServers.stream().anyMatch(wrapper -> wrapper.serverDefinition.equals(serverDefinition) && wrapper.canOperate(document))) {
// we already checked a compatible LS with this definition
continue;
}
final IProject fileProject = file != null ? file.getProject() : null;
LanguageServerWrapper wrapper = fileProject != null ? new LanguageServerWrapper(fileProject, serverDefinition) : new LanguageServerWrapper(serverDefinition, path);
startedServers.add(wrapper);
res.add(wrapper);
}
if (contentType.getBaseType() != null) {
contentTypes.add(contentType.getBaseType());
}
processedContentTypes.add(contentType);
}
return res;
}
}
Aggregations