From 00d423a7ea252c20fdf53f023bb46e1e05d6ec28 Mon Sep 17 00:00:00 2001 From: aboyko Date: Mon, 14 Oct 2024 13:09:58 -0400 Subject: [PATCH] Setting to "elide prefix" for properties completions --- .../tooling/boot/ls/Constants.java | 2 ++ .../ls/DelegatingStreamConnectionProvider.java | 6 ++++++ .../boot/ls/prefs/BootJavaPreferencesPage.java | 3 +++ .../tooling/boot/ls/prefs/PrefsInitializer.java | 2 ++ .../ide/vscode/boot/app/BootJavaConfig.java | 8 ++++++++ .../boot/app/BootLanguageServerBootApp.java | 4 ++-- .../PropertiesCompletionProposalsCalculator.java | 7 +++++-- .../completions/PropertyCompletionSettings.java | 15 +++++++++++++++ .../SpringPropertiesCompletionEngine.java | 16 ++++++++++------ .../test/ApplicationPropertiesEditorTest.java | 16 +++++++++++++--- .../vscode-spring-boot/package.json | 5 +++++ 11 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertyCompletionSettings.java diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/Constants.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/Constants.java index a20ccd7a6..fd44f6500 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/Constants.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/Constants.java @@ -48,4 +48,6 @@ public class Constants { public static final String PREF_JPQL = "boot-java.jpql"; + public static final String PREF_PROPS_COMPLETIONS_ELIDE_PREFIX = "boot-java.properties.completions.elide-prefix"; + } diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java index 69144c218..cef1dcbb8 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java @@ -223,6 +223,12 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi "properties-metadata", preferenceStore.getString(Constants.PREF_COMMON_PROPS_METADATA) )); + bootJavaObj.put("properties", Map.of( + "completions", Map.of( + "elide-prefix", preferenceStore.getBoolean(Constants.PREF_PROPS_COMPLETIONS_ELIDE_PREFIX) + ) + )); + settings.put("boot-java", bootJavaObj); settings.put("http", createHttpProxySettings()); diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/BootJavaPreferencesPage.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/BootJavaPreferencesPage.java index 1e7ef4621..272f90d16 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/BootJavaPreferencesPage.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/BootJavaPreferencesPage.java @@ -45,6 +45,9 @@ public class BootJavaPreferencesPage extends FieldEditorPreferencePage implement // JPQL Support switch addField(new BooleanFieldEditor(Constants.PREF_JPQL, "JPA Query language support", fieldEditorParent)); + + // Properties Completions - Elide common prefix + addField(new BooleanFieldEditor(Constants.PREF_PROPS_COMPLETIONS_ELIDE_PREFIX, "Elide common prefix in property key auto completions", fieldEditorParent)); // Experimental Modulith support addField(new BooleanFieldEditor(Constants.PREF_MODULITH, "Spring Boot Modulith automatic project tracking and metadata update", fieldEditorParent)); diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/PrefsInitializer.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/PrefsInitializer.java index 18e661218..9fab28f68 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/PrefsInitializer.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/prefs/PrefsInitializer.java @@ -66,6 +66,8 @@ public class PrefsInitializer extends AbstractPreferenceInitializer { preferenceStore.setDefault(Constants.PREF_JPQL, true); + preferenceStore.setDefault(Constants.PREF_PROPS_COMPLETIONS_ELIDE_PREFIX, false); + } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootJavaConfig.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootJavaConfig.java index 4734fc0a3..ea79e3e41 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootJavaConfig.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootJavaConfig.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.ide.vscode.boot.common.SpringProblemCategories; +import org.springframework.ide.vscode.boot.properties.completions.PropertyCompletionSettings; import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemCategory.Toggle; import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType; import org.springframework.ide.vscode.commons.languageserver.util.ListenerList; @@ -235,6 +236,13 @@ public class BootJavaConfig implements InitializingBean { return Toggle.Option.AUTO; } + public PropertyCompletionSettings getPropertyCompletionSettings() { + Boolean elidePrefix = settings.getBoolean("boot-java", "properties", "completions", "elide-prefix"); + return new PropertyCompletionSettings( + elidePrefix != null && elidePrefix.booleanValue() + ); + } + public JsonObject getJavaValidationSettingsJson() { JsonObject javaValidationsJson = new JsonObject(); List javaValidationTypes = List.of( diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java index ef2962749..a61416f8a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java @@ -286,11 +286,11 @@ public class BootLanguageServerBootApp { return new SpringXMLCompletionEngine(server, projectFinder, symbolIndex, config); } - @Bean SpringPropertiesCompletionEngine propertiesCompletionEngine(BootLanguageServerParams params, JavaProjectFinder projectFinder, SourceLinks sourceLinks) { + @Bean SpringPropertiesCompletionEngine propertiesCompletionEngine(BootLanguageServerParams params, JavaProjectFinder projectFinder, SourceLinks sourceLinks, BootJavaConfig config) { return new SpringPropertiesCompletionEngine( params.indexProvider, params.typeUtilProvider, - projectFinder, sourceLinks); + projectFinder, sourceLinks, config); } @Bean YamlCompletionEngine yamlCompletionEngine(YamlStructureProvider structureProvider, YamlAssistContextProvider contextProvider) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertiesCompletionProposalsCalculator.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertiesCompletionProposalsCalculator.java index 7a826d969..7004fc28b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertiesCompletionProposalsCalculator.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertiesCompletionProposalsCalculator.java @@ -116,9 +116,12 @@ public class PropertiesCompletionProposalsCalculator { private int offset; private boolean preferLowerCaseEnums; private AntlrParser parser; + private final PropertyCompletionSettings propertyCompletionSettings; - public PropertiesCompletionProposalsCalculator(FuzzyMap index, TypeUtil typeUtil, PropertyCompletionFactory completionFactory, IDocument doc, int offset, boolean preferLowerCaseEnums) { + public PropertiesCompletionProposalsCalculator(FuzzyMap index, PropertyCompletionSettings propertyCompletionSettings, + TypeUtil typeUtil, PropertyCompletionFactory completionFactory, IDocument doc, int offset, boolean preferLowerCaseEnums) { this.index = index; + this.propertyCompletionSettings = propertyCompletionSettings; this.typeUtil = typeUtil; this.completionFactory = completionFactory; this.doc = doc; @@ -365,7 +368,7 @@ public class PropertiesCompletionProposalsCalculator { } private Collection elideCommonPrefix(String basePrefix, ArrayList proposals) { - if (false) { // TODO: check for preference setting + if (propertyCompletionSettings.elidePrefix()) { String prefix = StringUtil.commonPrefix(Stream.concat(Stream.of(basePrefix), proposals.stream().map(ICompletionProposal::getLabel))); int lastDot = prefix.lastIndexOf('.'); if (lastDot>=0) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertyCompletionSettings.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertyCompletionSettings.java new file mode 100644 index 000000000..90c9d436b --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/PropertyCompletionSettings.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2024 Broadcom, 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 + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.properties.completions; + +public record PropertyCompletionSettings(boolean elidePrefix) { + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java index f0f0885a4..fd2311e36 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java @@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.properties.completions; import java.util.Collection; +import org.springframework.ide.vscode.boot.app.BootJavaConfig; import org.springframework.ide.vscode.boot.common.PropertyCompletionFactory; import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; @@ -35,18 +36,21 @@ public class SpringPropertiesCompletionEngine implements ICompletionEngine, Lang private boolean preferLowerCaseEnums = true; //might make sense to make this user configurable - private SpringPropertyIndexProvider indexProvider; - private TypeUtilProvider typeUtilProvider; - private PropertyCompletionFactory completionFactory = null; - private SourceLinks sourceLinks; + private final SpringPropertyIndexProvider indexProvider; + private final TypeUtilProvider typeUtilProvider; + private final PropertyCompletionFactory completionFactory; + private final SourceLinks sourceLinks; + private final BootJavaConfig config; /** * Constructor used in 'production'. Wires up stuff properly for running inside a normal * Eclipse runtime. */ - public SpringPropertiesCompletionEngine(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder, SourceLinks sourceLinks) { + public SpringPropertiesCompletionEngine(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder, + SourceLinks sourceLinks, BootJavaConfig config) { this.indexProvider = indexProvider; this.typeUtilProvider = typeUtilProvider; + this.config = config; this.completionFactory = new PropertyCompletionFactory(); this.sourceLinks = sourceLinks; } @@ -56,7 +60,7 @@ public class SpringPropertiesCompletionEngine implements ICompletionEngine, Lang */ @Override public InternalCompletionList getCompletions(TextDocument doc, int offset) throws BadLocationException { - Collection completionItems = new PropertiesCompletionProposalsCalculator(indexProvider.getIndex(doc).getProperties(), + Collection completionItems = new PropertiesCompletionProposalsCalculator(indexProvider.getIndex(doc).getProperties(), config.getPropertyCompletionSettings(), typeUtilProvider.getTypeUtil(sourceLinks, doc), completionFactory, doc, offset, preferLowerCaseEnums).calculate(); return new InternalCompletionList(completionItems, true); diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java index 2b9aba1e2..084536cf0 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java @@ -42,6 +42,7 @@ import org.springframework.ide.vscode.boot.metadata.CachingValueProvider; import org.springframework.ide.vscode.boot.metadata.PropertiesLoader; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.java.IType; +import org.springframework.ide.vscode.commons.languageserver.util.Settings; import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.languageserver.testharness.CodeAction; @@ -51,6 +52,8 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import com.google.common.collect.ImmutableList; import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.JsonElement; /** * Boot App Properties Editor tests @@ -292,6 +295,13 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest { @Test void abbreviateLongPrefixCompletions() throws Exception { + + String changedSettings = "{\"boot-java\": {\"properties\": {\"completions\": {\"elide-prefix\": true}}}}"; + JsonElement settingsAsJson = new Gson().fromJson(changedSettings, JsonElement.class); + Settings settings = new Settings(settingsAsJson); + + harness.changeConfiguration(settings); + //See: https://github.com/spring-projects/sts4/issues/361 Editor editor; @@ -815,9 +825,9 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest { assertCompletionsDisplayString( "application.temp.user.<*>" , // => - "name", - "password", - "roles" + "application.temp.user.name", + "application.temp.user.password", + "application.temp.user.roles" ); assertCompletionsDisplayString( diff --git a/vscode-extensions/vscode-spring-boot/package.json b/vscode-extensions/vscode-spring-boot/package.json index 64e3472cd..14d3d2963 100644 --- a/vscode-extensions/vscode-spring-boot/package.json +++ b/vscode-extensions/vscode-spring-boot/package.json @@ -343,6 +343,11 @@ ], "description": "The path to a shared properties metadata JSON file." }, + "boot-java.properties.completions.elide-prefix": { + "type": "boolean", + "default": false, + "description": "Elide common prefix in property key auto completions" + }, "boot-java.jpql": { "type": "boolean", "default": true,