diff --git a/org.eclipse.lsp4e/plugin.properties b/org.eclipse.lsp4e/plugin.properties
index 7046593a7..1d939a168 100644
--- a/org.eclipse.lsp4e/plugin.properties
+++ b/org.eclipse.lsp4e/plugin.properties
@@ -22,6 +22,7 @@ codeactions.menu.label=Code Actions
languageservers.preferences.page=Language Servers
languageservers.preferences.folding.page=Folding
languageservers.preferences.formatter.page=Formatter
+languageservers.preferences.contentassist.page=Content Assist
languageservers.preferences.logging.page=Logs
notification.category.label = LSP
notification.event.label = LSP Notification
diff --git a/org.eclipse.lsp4e/plugin.xml b/org.eclipse.lsp4e/plugin.xml
index e4506139c..544de53ad 100644
--- a/org.eclipse.lsp4e/plugin.xml
+++ b/org.eclipse.lsp4e/plugin.xml
@@ -138,6 +138,12 @@
id="org.eclipse.lsp4e.preferences.formatter"
name="%languageservers.preferences.formatter.page">
+
+
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/completion/LSContentAssistProcessor.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/completion/LSContentAssistProcessor.java
index 7de43c7d7..e2e50fd66 100644
--- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/completion/LSContentAssistProcessor.java
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/completion/LSContentAssistProcessor.java
@@ -33,6 +33,7 @@
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
@@ -43,12 +44,15 @@
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4e.LanguageServerPlugin;
import org.eclipse.lsp4e.LanguageServerWrapper;
import org.eclipse.lsp4e.LanguageServers;
import org.eclipse.lsp4e.internal.CancellationSupport;
import org.eclipse.lsp4e.internal.CancellationUtil;
+import org.eclipse.lsp4e.ui.ContentAssistPreferencePage;
import org.eclipse.lsp4e.ui.Messages;
import org.eclipse.lsp4e.ui.UI;
import org.eclipse.lsp4j.CompletionItem;
@@ -66,6 +70,16 @@
import com.google.common.base.Strings;
public class LSContentAssistProcessor implements IContentAssistProcessor {
+ private final IPreferenceStore prefStore = LanguageServerPlugin.getDefault().getPreferenceStore();
+ private boolean invokeAfterSemicolon = prefStore.getBoolean(ContentAssistPreferencePage.INVOKE_AFTER_SEMICOLON_ENABLED);
+ private final IPropertyChangeListener contentAssistPrefsListener = (final PropertyChangeEvent event) -> {
+ final var newValue = event.getNewValue();
+ if (newValue != null) {
+ if (event.getProperty() == ContentAssistPreferencePage.INVOKE_AFTER_SEMICOLON_ENABLED) {
+ invokeAfterSemicolon = Boolean.parseBoolean(newValue.toString());
+ }
+ }
+ };
private static final ICompletionProposal[] NO_COMPLETION_PROPOSALS = new ICompletionProposal[0];
private static final long TRIGGERS_TIMEOUT = 50;
@@ -105,6 +119,7 @@ public LSContentAssistProcessor(boolean errorAsCompletionItem, boolean incomplet
this.completionCancellationSupport = new CancellationSupport();
this.triggerCharsCancellationSupport = new CancellationSupport();
this.incompleteAsCompletionItem = incompleteAsCompletionItem;
+ prefStore.addPropertyChangeListener(contentAssistPrefsListener);
}
private final Comparator proposalComparator = new LSCompletionProposalComparator();
@@ -124,6 +139,18 @@ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int
initiateLanguageServers(document);
CompletionParams param;
+ if (!invokeAfterSemicolon && document.getLength() > 0) {
+ int positionCharacterOffset = offset > 0 ? offset-1 : offset;
+ try {
+ var trigChar = document.get(positionCharacterOffset, 1);
+ if (";".equals(trigChar)) { //$NON-NLS-1$
+ return NO_COMPLETION_PROPOSALS;
+ }
+ } catch (BadLocationException e) {
+ LanguageServerPlugin.logError(e);
+ }
+ }
+
try {
param = LSPEclipseUtils.toCompletionParams(uri, offset, document, this.completionTriggerChars);
} catch (BadLocationException e) {
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/ContentAssistPreferencePage.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/ContentAssistPreferencePage.java
new file mode 100644
index 000000000..a3ff27646
--- /dev/null
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/ContentAssistPreferencePage.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Contributors to the Eclipse Foundation.
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * See git history
+ *******************************************************************************/
+package org.eclipse.lsp4e.ui;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.lsp4e.LanguageServerPlugin;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class ContentAssistPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+ public static final String INVOKE_AFTER_SEMICOLON_ENABLED = "invokeContentAssistOnSemicolon.enabled"; //$NON-NLS-1$
+
+ public static final class PreferenceInitializer extends AbstractPreferenceInitializer {
+ @Override
+ public void initializeDefaultPreferences() {
+ final var store = LanguageServerPlugin.getDefault().getPreferenceStore();
+ store.setDefault(INVOKE_AFTER_SEMICOLON_ENABLED, false);
+ }
+ }
+
+ public ContentAssistPreferencePage() {
+ super(GRID);
+ setPreferenceStore(LanguageServerPlugin.getDefault().getPreferenceStore());
+ }
+
+ @Override
+ public void createFieldEditors() {
+ final Composite parent = getFieldEditorParent();
+
+ /*
+ * check box to globally enable/disable on type formatting
+ */
+ final var foldingEnabled = new BooleanFieldEditor( //
+ INVOKE_AFTER_SEMICOLON_ENABLED, //
+ Messages.PreferencesPage_enableTriggerContentAssistOnSemicolon, //
+ parent);
+ addField(foldingEnabled);
+
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
+}
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java
index 029f317d4..b613fad24 100644
--- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java
@@ -48,6 +48,7 @@ public final class Messages extends NLS {
public static String PreferencesPage_restartWarning_message;
public static String PreferencesPage_restartWarning_restart;
public static String PreferencesPage_enableOnTypeFormatting;
+ public static String PreferencesPage_enableTriggerContentAssistOnSemicolon;
public static String NewContentTypeLSPLaunchDialog_associateContentType;
public static String NewContentTypeLSPLaunchDialog_withLSPLaunch;
public static String codeActions_description;
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties
index 0006d2f93..8b093a842 100644
--- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties
@@ -42,6 +42,7 @@ PreferencesPage_restartWarning_title=Restart Required
PreferencesPage_restartWarning_message=Changes to the logging settings may require a restart to fully take affect. Would you like to restart Eclipse SDK to apply the changes?
PreferencesPage_restartWarning_restart=Restart Now
PreferencesPage_enableOnTypeFormatting=Enable on type formatting
+PreferencesPage_enableTriggerContentAssistOnSemicolon=Enable trigger on semicolon
NewContentTypeLSPLaunchDialog_associateContentType=Associate content-type...
NewContentTypeLSPLaunchDialog_withLSPLaunch=...with Language Server Launch Configuration