blob: 7d9df9e387251d8ad0c59b472e0b3e4a3e84dff4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2021 Red Hat Inc. 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:
* Victor Rubezhny (Red Hat Inc.) - initial implementation
*******************************************************************************/
package org.eclipse.lsp4e.operations.linkedediting;
import java.net.URI;
import java.util.concurrent.CompletableFuture;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4e.LanguageServerPlugin;
import org.eclipse.lsp4e.LanguageServiceAccessor;
import org.eclipse.lsp4j.LinkedEditingRanges;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.TextDocumentPositionParams;
public class LSPLinkedEditingBase implements IPreferenceChangeListener {
public static final String LINKED_EDITING_PREFERENCE = "org.eclipse.ui.genericeditor.linkedediting"; //$NON-NLS-1$
protected LinkedEditingRanges fLinkedEditingRanges;
private CompletableFuture<Void> request;
protected boolean fEnabled;
protected void install() {
IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(LanguageServerPlugin.PLUGIN_ID);
preferences.addPreferenceChangeListener(this);
this.fEnabled = preferences.getBoolean(LINKED_EDITING_PREFERENCE, true);
}
protected void uninstall() {
IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(LanguageServerPlugin.PLUGIN_ID);
preferences.removePreferenceChangeListener(this);
cancel();
}
protected CompletableFuture<Void> collectLinkedEditingRanges(IDocument document, int offset) {
fLinkedEditingRanges = null;
cancel();
if (document == null) {
return CompletableFuture.completedFuture(null);
}
Position position;
try {
position = LSPEclipseUtils.toPosition(offset, document);
} catch (BadLocationException e) {
LanguageServerPlugin.logError(e);
return CompletableFuture.completedFuture(null);
}
URI uri = LSPEclipseUtils.toUri(document);
if(uri == null) {
return CompletableFuture.completedFuture(null);
}
TextDocumentIdentifier identifier = new TextDocumentIdentifier(uri.toString());
TextDocumentPositionParams params = new TextDocumentPositionParams(identifier, position);
return request = LanguageServiceAccessor.getLanguageServers(document,
capabilities -> LSPEclipseUtils.hasCapability(capabilities.getLinkedEditingRangeProvider()))
.thenComposeAsync(languageServers ->
CompletableFuture.allOf(languageServers.stream()
.map(ls -> ls.getTextDocumentService().linkedEditingRange(LSPEclipseUtils.toLinkedEditingRangeParams(params))
.thenAcceptAsync(result -> fLinkedEditingRanges = result))
.toArray(CompletableFuture[]::new)));
}
/**
* Cancel the last call of 'linkedEditing'.
*/
private void cancel() {
if (request != null && !request.isDone()) {
request.cancel(true);
request = null;
}
}
@Override
public void preferenceChange(PreferenceChangeEvent event) {
if (event.getKey().equals(LINKED_EDITING_PREFERENCE)) {
this.fEnabled = Boolean.valueOf(event.getNewValue().toString());
}
}
}