Skip to content

Commit

Permalink
feat: support auto folding of comments and add folding preferences page
Browse files Browse the repository at this point in the history
  • Loading branch information
sebthom committed Jan 11, 2025
1 parent e7dda3d commit 6aea332
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 15 deletions.
5 changes: 3 additions & 2 deletions org.eclipse.lsp4e/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ openDeclarationHyperlink_name=Go to declaration
openDeclarationHyperlink_description=Get to the location where this element is declared
refactorings.menu.label=Refactorings
codeactions.menu.label=Code Actions
languageservers.preference.page=Language Servers
languageservers.logging.preference.page=Logs
languageservers.preferences.page=Language Servers
languageservers.preferences.folding.page=Folding
languageservers.preferences.logging.page=Logs
notification.category.label = LSP
notification.event.label = LSP Notification
command.toggle.highlight.label = Toggle Mark Occurrences
Expand Down
12 changes: 9 additions & 3 deletions org.eclipse.lsp4e/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,19 @@
<page
class="org.eclipse.lsp4e.ui.LanguageServerPreferencePage"
id="org.eclipse.lsp4e.preferences"
name="%languageservers.preference.page">
name="%languageservers.preferences.page">
</page>
<page
category="org.eclipse.lsp4e.preferences"
class="org.eclipse.lsp4e.ui.LoggingPreferencePage"
id="org.eclipse.lsp4e.logging.preferences"
name="%languageservers.logging.preference.page">
id="org.eclipse.lsp4e.preferences.logging"
name="%languageservers.preferences.logging.page">
</page>
<page
category="org.eclipse.lsp4e.preferences"
class="org.eclipse.lsp4e.ui.FoldingPreferencePage"
id="org.eclipse.lsp4e.preferences.folding"
name="%languageservers.preferences.folding.page">
</page>
</extension>
<extension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*
* Contributors:
* Angelo Zerr <[email protected]> - Add support for 'textDocument/foldingRange' - Bug 537706
* Sebastian Thomschke (Vegard IT GmbH) - Add comments/region default folding and folding prefs listener
*/
package org.eclipse.lsp4e.operations.folding;

Expand Down Expand Up @@ -38,10 +39,13 @@
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
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.LanguageServers;
import org.eclipse.lsp4e.internal.DocumentUtil;
import org.eclipse.lsp4e.ui.FoldingPreferencePage;
import org.eclipse.lsp4j.FoldingRange;
import org.eclipse.lsp4j.FoldingRangeKind;
import org.eclipse.lsp4j.FoldingRangeRequestParams;
Expand All @@ -52,9 +56,7 @@
import org.eclipse.swt.widgets.Canvas;

/**
* LSP folding reconcilinig strategy which consumes the
* `textDocument/foldingRange` command.
*
* LSP folding reconcilinig strategy which consumes the `textDocument/foldingRange` command.
*/
public class LSPFoldingReconcilingStrategy
implements IReconcilingStrategy, IReconcilingStrategyExtension, IProjectionListener, ITextViewerLifecycle {
Expand All @@ -66,12 +68,27 @@ public class LSPFoldingReconcilingStrategy
private @Nullable ProjectionViewer viewer;
private List<CompletableFuture<@Nullable List<FoldingRange>>> requests = List.of();
private volatile long timestamp = 0;
private final boolean collapseImports;

public LSPFoldingReconcilingStrategy() {
IPreferenceStore store = LanguageServerPlugin.getDefault().getPreferenceStore();
collapseImports = store.getBoolean("foldingReconcilingStrategy.collapseImports"); //$NON-NLS-1$
}
private final IPreferenceStore prefStore = LanguageServerPlugin.getDefault().getPreferenceStore();
private boolean collapseComments = prefStore.getBoolean(FoldingPreferencePage.PREF_COLLAPSE_COMMENTS);
private boolean collapseFoldingRegions = prefStore.getBoolean(FoldingPreferencePage.PREF_COLLAPSE_FOLDING_REGIONS);
private boolean collapseImports = prefStore.getBoolean(FoldingPreferencePage.PREF_COLLAPSE_IMPORT_STATEMENTS);
private final IPropertyChangeListener foldingPrefsListener = (final PropertyChangeEvent event) -> {
final var newValue = event.getNewValue();
if (newValue != null) {
switch (event.getProperty()) {
case FoldingPreferencePage.PREF_COLLAPSE_COMMENTS:
collapseComments = Boolean.parseBoolean(newValue.toString());
break;
case FoldingPreferencePage.PREF_COLLAPSE_FOLDING_REGIONS:
collapseFoldingRegions = Boolean.parseBoolean(newValue.toString());
break;
case FoldingPreferencePage.PREF_COLLAPSE_IMPORT_STATEMENTS:
collapseImports = Boolean.parseBoolean(newValue.toString());
break;
}
}
};

/**
* A FoldingAnnotation is a {@link ProjectionAnnotation} it is folding and
Expand Down Expand Up @@ -165,9 +182,15 @@ private void applyFolding(@Nullable List<FoldingRange> ranges) {
.sorted(Comparator.comparing(FoldingRange::getEndLine)) //
.forEach(foldingRange -> {
try {
final var collapsByDefault = foldingRange.getKind() != null
&& switch (foldingRange.getKind()) {
case FoldingRangeKind.Comment -> collapseComments;
case FoldingRangeKind.Imports -> collapseImports;
case FoldingRangeKind.Region -> collapseFoldingRegions;
default -> false;
};
updateAnnotation(deletions, existing, additions, foldingRange.getStartLine(),
foldingRange.getEndLine(),
collapseImports && FoldingRangeKind.Imports.equals(foldingRange.getKind()));
foldingRange.getEndLine(), collapsByDefault);
} catch (BadLocationException e) {
// should never occur
}
Expand Down Expand Up @@ -196,6 +219,7 @@ public void install(ITextViewer viewer) {
this.viewer = projViewer;
projViewer.addProjectionListener(this);
this.projectionAnnotationModel = projViewer.getProjectionAnnotationModel();
prefStore.addPropertyChangeListener(foldingPrefsListener);
}
}

Expand All @@ -205,6 +229,7 @@ public void uninstall() {
if (viewer != null) {
viewer.removeProjectionListener(this);
viewer = null;
prefStore.removePropertyChangeListener(foldingPrefsListener);
}
projectionDisabled();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2025 Vegard IT GmbH and others.
* 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:
* Sebastian Thomschke (Vegard IT GmbH) - initial implementation.
*******************************************************************************/
package org.eclipse.lsp4e.ui;

import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.lsp4e.LanguageServerPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

public class FoldingPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {

public static final String PREF_COLLAPSE_COMMENTS = "foldingReconcilingStrategy.collapseComments"; //$NON-NLS-1$
public static final String PREF_COLLAPSE_FOLDING_REGIONS = "foldingReconcilingStrategy.collapseFoldingRegions"; //$NON-NLS-1$
public static final String PREF_COLLAPSE_IMPORT_STATEMENTS = "foldingReconcilingStrategy.collapseImports"; //$NON-NLS-1$

public FoldingPreferencePage() {
super(GRID);
setPreferenceStore(LanguageServerPlugin.getDefault().getPreferenceStore());
}

@Override
public void createFieldEditors() {
Composite parent = getFieldEditorParent();

// Add a label before the field editors
final var label = new Label(parent, SWT.NONE);
label.setText("Initially fold these elements:"); //$NON-NLS-1$
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

// Add check boxes
addField(new BooleanFieldEditor( //
PREF_COLLAPSE_COMMENTS, //
"Comments", //$NON-NLS-1$
parent));
addField(new BooleanFieldEditor( //
PREF_COLLAPSE_COMMENTS, //
"Folding Regions", //$NON-NLS-1$
parent));
addField(new BooleanFieldEditor( //
PREF_COLLAPSE_IMPORT_STATEMENTS, //
"Import statements", //$NON-NLS-1$
parent));
}

@Override
public void init(IWorkbench workbench) {
// Initialization logic if needed
}
}

0 comments on commit 6aea332

Please sign in to comment.