diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java index 1e289928a..5ae8e9ac8 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java @@ -29,6 +29,7 @@ import org.springframework.ide.vscode.boot.xml.completions.TypeCompletionProposa import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.util.text.TextDocument; /** @@ -48,10 +49,10 @@ public class SpringXMLCompletionEngine implements ICompletionEngine { private final Map completionProviders; public SpringXMLCompletionEngine(SpringXMLLanguageServerComponents springXMLLanguageServerComponents, - JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex) { + JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex, SimpleTextDocumentService simpleTextDocumentService) { this.completionProviders = new HashMap<>(); - this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, null, BEAN_ELEMENT, CLASS_ATTRIBUTE), new TypeCompletionProposalProvider(projectFinder, true)); + this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, null, BEAN_ELEMENT, CLASS_ATTRIBUTE), new TypeCompletionProposalProvider(projectFinder, simpleTextDocumentService, true)); this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, BEAN_ELEMENT, PROPERTY_ELEMENT, NAME_ATTRIBUTE), new PropertyNameCompletionProposalProvider(projectFinder)); this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, BEAN_ELEMENT, PROPERTY_ELEMENT, REF_ATTRIBUTE), new BeanRefCompletionProposalProvider(projectFinder, symbolIndex)); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java index e7850f88b..ce9d8767c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java @@ -38,6 +38,7 @@ public class SpringXMLLanguageServerComponents implements LanguageServerComponen private final BootLanguageServerParams serverParams; private final JavaProjectFinder projectFinder; private final SpringSymbolIndex symbolIndex; + private final SpringXMLCompletionEngine completionEngine; public SpringXMLLanguageServerComponents( SimpleLanguageServer server, @@ -51,6 +52,8 @@ public class SpringXMLLanguageServerComponents implements LanguageServerComponen server.doOnInitialized(this::initialized); server.onShutdown(this::shutdown); + + this.completionEngine = new SpringXMLCompletionEngine(this, projectFinder, symbolIndex, server.getTextDocumentService()); } @Override @@ -60,7 +63,7 @@ public class SpringXMLLanguageServerComponents implements LanguageServerComponen @Override public ICompletionEngine getCompletionEngine() { - return new SpringXMLCompletionEngine(this, projectFinder, symbolIndex); + return this.completionEngine; } @Override diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/completions/TypeCompletionProposalProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/completions/TypeCompletionProposalProvider.java index 632f5c0e1..c2d82c652 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/completions/TypeCompletionProposalProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/completions/TypeCompletionProposalProvider.java @@ -12,7 +12,9 @@ package org.springframework.ide.vscode.boot.xml.completions; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.Optional; +import java.util.Set; import org.eclipse.lsp4j.CompletionItemKind; import org.eclipse.lsp4xml.dom.DOMAttr; @@ -24,6 +26,7 @@ import org.springframework.ide.vscode.commons.java.IType; import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.util.Renderable; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -37,10 +40,15 @@ public class TypeCompletionProposalProvider implements XMLCompletionProvider { private final JavaProjectFinder projectFinder; private final boolean classesOnly; + private final Set typeSearchAlreadyInitializedProjects = Collections.synchronizedSet(new HashSet<>()); - public TypeCompletionProposalProvider(JavaProjectFinder projectFinder, boolean classesOnly) { + public TypeCompletionProposalProvider(JavaProjectFinder projectFinder, SimpleTextDocumentService simpleTextDocumentService, boolean classesOnly) { this.projectFinder = projectFinder; this.classesOnly = classesOnly; + + simpleTextDocumentService.onDidOpen(doc -> { + initializeTypeSearch(doc); + }); } @Override @@ -107,4 +115,22 @@ public class TypeCompletionProposalProvider implements XMLCompletionProvider { return new TypeCompletionProposal(label, kind, edits, type.getFullyQualifiedName(), renderable, t.getT2()); } + /** + * trigger initial type search as soon as the doc opens to avoid search timeouts when doing type proposals for the first time + */ + private void initializeTypeSearch(TextDocument doc) { + Optional foundProject = this.projectFinder.find(doc.getId()); + if (foundProject.isPresent()) { + IJavaProject project = foundProject.get(); + String projectName = project.getElementName(); + + if (!this.typeSearchAlreadyInitializedProjects.contains(projectName)) { + + this.typeSearchAlreadyInitializedProjects.add(projectName); + Flux> types = project.getIndex().camelcaseSearchTypes("", true, true); + types.count(); + } + } + } + }