Make ls.eclipse.gotosymbol plugin part of boot.java.ls.feature
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.springframework.tooling.ls.eclipse.gotosymbol</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,106 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
|
||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.APILeak=warning
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -1,24 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Goto Symbol Popup
|
||||
Bundle-SymbolicName: org.springframework.tooling.ls.eclipse.gotosymbol;singleton:=true
|
||||
Bundle-Version: 0.0.10.qualifier
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
org.eclipse.ui.workbench.texteditor,
|
||||
org.eclipse.lsp4e,
|
||||
org.eclipse.lsp4j,
|
||||
org.eclipse.jface.text;bundle-version="3.12.0",
|
||||
org.eclipse.core.resources;bundle-version="3.12.0",
|
||||
org.eclipse.core.filebuffers,
|
||||
org.eclipse.ui.navigator,
|
||||
org.eclipse.equinox.registry,
|
||||
org.springsource.ide.eclipse.commons.livexp,
|
||||
com.google.guava,
|
||||
org.eclipse.core.jobs,
|
||||
org.eclipse.core.runtime;bundle-version="3.13.0",
|
||||
org.springframework.ide.eclipse.boot,
|
||||
org.springsource.ide.eclipse.commons.core
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-Activator: org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Vendor: Pivotal, Inc.
|
||||
@@ -1,6 +0,0 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = plugin.xml,\
|
||||
META-INF/,\
|
||||
.,\
|
||||
icons/
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 332 B |
Binary file not shown.
|
Before Width: | Height: | Size: 526 B |
@@ -1,66 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<category
|
||||
name="STS4"
|
||||
id="org.springframework.tooling.ls.eclipse.gotosymbol.commands.category">
|
||||
</category>
|
||||
<command
|
||||
name="Goto Symbol"
|
||||
categoryId="org.springframework.tooling.ls.eclipse.gotosymbol.commands.category"
|
||||
defaultHandler="org.springframework.tooling.ls.eclipse.gotosymbol.handlers.GotoSymbolHandler"
|
||||
id="org.springframework.tooling.ls.eclipse.gotosymbol.command">
|
||||
</command>
|
||||
</extension>
|
||||
<!-- <extension
|
||||
point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
commandId="org.springframework.tooling.ls.eclipse.gotosymbol.command"
|
||||
class="org.springframework.tooling.ls.eclipse.gotosymbol.handlers.GotoSymbolHandler">
|
||||
</handler>
|
||||
</extension> -->
|
||||
<extension
|
||||
point="org.eclipse.ui.bindings">
|
||||
<key
|
||||
commandId="org.springframework.tooling.ls.eclipse.gotosymbol.command"
|
||||
contextId="org.eclipse.ui.contexts.dialogAndWindow"
|
||||
sequence="M1+6"
|
||||
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
|
||||
</key>
|
||||
</extension>
|
||||
<!-- TODO: stuff below comes from 'Hello world Command' example generated by Eclipse
|
||||
Should figure out proper way to integrate into menus and toolbars etc. So commented out
|
||||
The command is currently accessible only via 'Quick Access' search box or keyboard shortcut
|
||||
<extension
|
||||
point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="menu:org.eclipse.ui.main.menu?after=additions">
|
||||
<menu
|
||||
label="Sample Menu"
|
||||
mnemonic="M"
|
||||
id="org.springframework.tooling.ls.eclipse.gotosymbol.menus.sampleMenu">
|
||||
<command
|
||||
commandId="org.springframework.tooling.ls.eclipse.gotosymbol.command"
|
||||
mnemonic="G"
|
||||
id="org.springframework.tooling.ls.eclipse.gotosymbol.menus.sampleCommand">
|
||||
</command>
|
||||
</menu>
|
||||
</menuContribution>
|
||||
<menuContribution
|
||||
locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
|
||||
<toolbar
|
||||
id="org.springframework.tooling.ls.eclipse.gotosymbol.toolbars.sampleToolbar">
|
||||
<command
|
||||
commandId="org.springframework.tooling.ls.eclipse.gotosymbol.commands.sampleCommand"
|
||||
icon="icons/sample.png"
|
||||
tooltip="Say hello world"
|
||||
id="org.springframework.tooling.ls.eclipse.gotosymbol.toolbars.sampleCommand">
|
||||
</command>
|
||||
</toolbar>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
</plugin>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot.ide</groupId>
|
||||
<artifactId>org.springframework.boot.ide</artifactId>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../eclipse-distribution/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.springframework.tooling.ls.eclipse.gotosymbol</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
<version>0.0.10-SNAPSHOT</version>
|
||||
|
||||
</project>
|
||||
@@ -1,31 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol;
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
public class GotoSymbolPlugin extends AbstractUIPlugin {
|
||||
|
||||
private static GotoSymbolPlugin instance;
|
||||
|
||||
public GotoSymbolPlugin() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
this.instance = this;
|
||||
}
|
||||
|
||||
public static GotoSymbolPlugin getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -1,335 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Rogue Wave Software Inc. and others.
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Michał Niewrzał (Rogue Wave Software Inc.) - initial implementation
|
||||
* Kris De Volder (Pivotal Inc) - Copied and adapted from
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||
import org.eclipse.jface.dialogs.PopupDialog;
|
||||
import org.eclipse.jface.layout.GridDataFactory;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITextSelection;
|
||||
import org.eclipse.jface.text.source.SourceViewer;
|
||||
import org.eclipse.jface.util.Geometry;
|
||||
import org.eclipse.jface.viewers.IDoubleClickListener;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||
import org.eclipse.jface.viewers.StructuredSelection;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.lsp4e.outline.SymbolsLabelProvider;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.StyledText;
|
||||
import org.eclipse.swt.events.KeyAdapter;
|
||||
import org.eclipse.swt.events.KeyEvent;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.eclipse.swt.widgets.TreeItem;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
import org.springframework.ide.eclipse.boot.util.Log;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.util.SwtConnect;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.UIValueListener;
|
||||
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class GotoSymbolDialog extends PopupDialog {
|
||||
|
||||
private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder");
|
||||
|
||||
private static void debug(String string) {
|
||||
if (DEBUG) {
|
||||
System.out.println(string);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SymbolsContentProvider implements ITreeContentProvider {
|
||||
|
||||
@Override
|
||||
public Object[] getChildren(Object parentElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getParent(Object element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildren(Object element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getElements(Object inputElement) {
|
||||
if (inputElement instanceof GotoSymbolDialogModel) {
|
||||
GotoSymbolDialogModel model = (GotoSymbolDialogModel) inputElement;
|
||||
return model.getSymbols().getValues().toArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private GotoSymbolDialogModel model;
|
||||
private List<Disposable> disposables = new ArrayList<>();
|
||||
private ITextEditor fTextEditor;
|
||||
|
||||
/**
|
||||
* If true, align the dialog so it looks like its attached right side of the editor. Otherwise, dialog is centered on the editor instead.
|
||||
*/
|
||||
private boolean alignRight;
|
||||
private IDialogSettings dlgSettings;
|
||||
|
||||
public GotoSymbolDialog(Shell parentShell, ITextEditor textEditor, GotoSymbolDialogModel model, boolean alignRight) {
|
||||
super(parentShell, PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE,
|
||||
/*focus*/true, /*persistSize*/true, /*persistLoc*/true,
|
||||
/*menu*/false, /*showPersistActions*/false, null, null
|
||||
);
|
||||
//Note: because of the way shell is initialized, the options to persist size / location do not work.
|
||||
// If we want this to work, it will have to be debugged.
|
||||
//For the time being I've simply disabled the menu that makes it appear like this should work.
|
||||
this.fTextEditor = textEditor;
|
||||
this.model = model;
|
||||
this.alignRight = alignRight;
|
||||
create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDialogSettings getDialogSettings() {
|
||||
if (dlgSettings==null) {
|
||||
this.dlgSettings = GotoSymbolPlugin.getInstance().getDialogSettings();
|
||||
}
|
||||
return dlgSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the 'target' for the dialog's action.
|
||||
*/
|
||||
private SymbolInformation getTarget(TreeViewer list) {
|
||||
ISelection sel = list.getSelection();
|
||||
if (sel instanceof IStructuredSelection) {
|
||||
IStructuredSelection ss = (IStructuredSelection) sel;
|
||||
Object selected = ss.getFirstElement();
|
||||
if (selected!=null) {
|
||||
return (SymbolInformation) selected;
|
||||
}
|
||||
}
|
||||
//No element selected, target the first element in the list instead.
|
||||
//This allows user to execute the action without explicitly selecting an element.
|
||||
return getFirstElement(list);
|
||||
}
|
||||
|
||||
private void installWidgetListeners(Text pattern, TreeViewer list) {
|
||||
pattern.addKeyListener(new KeyAdapter() {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.keyCode == SWT.ARROW_DOWN) {
|
||||
if (list.getTree().getItemCount() > 0) {
|
||||
list.getTree().setFocus();
|
||||
TreeItem[] items = list.getTree().getItems();
|
||||
if (items!=null && items.length>0) {
|
||||
list.getTree().setSelection(items[0]);
|
||||
//programatic selection may not fire selection events so...
|
||||
list.getTree().notifyListeners(SWT.Selection,
|
||||
new Event());
|
||||
}
|
||||
}
|
||||
} else if (e.character == '\r') {
|
||||
performOk(list);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
list.getTree().addKeyListener(new KeyAdapter() {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
|
||||
if (e.keyCode == SWT.ARROW_UP && (e.stateMask & SWT.SHIFT) == 0
|
||||
&& (e.stateMask & SWT.CTRL) == 0) {
|
||||
StructuredSelection selection = (StructuredSelection) list
|
||||
.getSelection();
|
||||
|
||||
if (selection.size() == 1) {
|
||||
Object element = selection.getFirstElement();
|
||||
if (element.equals(getFirstElement(list))) {
|
||||
pattern.setFocus();
|
||||
list.setSelection(new StructuredSelection());
|
||||
list.getTree().notifyListeners(SWT.Selection,
|
||||
new Event());
|
||||
}
|
||||
|
||||
}
|
||||
} else if (e.character == '\r') {
|
||||
performOk(list);
|
||||
}
|
||||
|
||||
// if (e.keyCode == SWT.ARROW_DOWN
|
||||
// && (e.stateMask & SWT.SHIFT) != 0
|
||||
// && (e.stateMask & SWT.CTRL) != 0) {
|
||||
//
|
||||
// list.getTree().notifyListeners(SWT.Selection, new Event());
|
||||
// }
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
list.addDoubleClickListener(e -> performOk(list));
|
||||
}
|
||||
|
||||
private void performOk(TreeViewer list) {
|
||||
if (model.performOk(getTarget(list))) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private SymbolInformation getFirstElement(TreeViewer list) {
|
||||
TreeItem[] items = list.getTree().getItems();
|
||||
if (items!=null && items.length>0) {
|
||||
TreeItem item = items[0];
|
||||
return (SymbolInformation) item.getData();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Control createDialogArea(Composite parent) {
|
||||
Composite dialogArea = new Composite(parent, SWT.NONE);
|
||||
dialogArea.addDisposeListener(de -> {
|
||||
for (Disposable d : disposables) {
|
||||
d.dispose();
|
||||
}
|
||||
});
|
||||
if (parent.getLayout() instanceof GridLayout) {
|
||||
dialogArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||
}
|
||||
|
||||
GridLayout layout = new GridLayout();
|
||||
layout.marginHeight = 0;
|
||||
layout.marginWidth = 0;
|
||||
dialogArea.setLayout(layout);
|
||||
|
||||
Text pattern = new Text(dialogArea, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
|
||||
// pattern.getAccessible().addAccessibleListener(new AccessibleAdapter() {
|
||||
// public void getName(AccessibleEvent e) {
|
||||
// e.result = LegacyActionTools.removeMnemonics(headerLabel)
|
||||
// .getText());
|
||||
// }
|
||||
// });
|
||||
pattern.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
SwtConnect.connect(pattern, model.getSearchBox());
|
||||
|
||||
TreeViewer viewer = new TreeViewer(dialogArea, SWT.SINGLE);
|
||||
GridDataFactory.fillDefaults().grab(true, true).applyTo(viewer.getControl());
|
||||
viewer.setContentProvider(new SymbolsContentProvider());
|
||||
viewer.setLabelProvider(new SymbolsLabelProvider());
|
||||
viewer.setUseHashlookup(true);
|
||||
disposables.add(model.getSymbols().onChange(UIValueListener.from((e, v) -> {
|
||||
viewer.refresh();
|
||||
})));
|
||||
//TODO: somehow show selection in local file, (but not in other file ?)
|
||||
// viewer.addSelectionChangedListener(event -> {
|
||||
// IStructuredSelection selection = (IStructuredSelection) event.getSelection();
|
||||
// if (selection.isEmpty()) {
|
||||
// return;
|
||||
// }
|
||||
// SymbolInformation symbolInformation = (SymbolInformation) selection.getFirstElement();
|
||||
// Location location = symbolInformation.getLocation();
|
||||
//
|
||||
// IResource targetResource = LSPEclipseUtils.findResourceFor(location.getUri());
|
||||
// if (targetResource == null) {
|
||||
// return;
|
||||
// }
|
||||
// IDocument targetDocument = FileBuffers.getTextFileBufferManager()
|
||||
// .getTextFileBuffer(targetResource.getFullPath(), LocationKind.IFILE).getDocument();
|
||||
// if (targetDocument != null) {
|
||||
// try {
|
||||
// int offset = LSPEclipseUtils.toOffset(location.getRange().getStart(), targetDocument);
|
||||
// int endOffset = LSPEclipseUtils.toOffset(location.getRange().getEnd(), targetDocument);
|
||||
// fTextEditor.selectAndReveal(offset, endOffset - offset);
|
||||
// } catch (BadLocationException e) {
|
||||
// LanguageServerPlugin.logError(e);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
installWidgetListeners(pattern, viewer);
|
||||
|
||||
Label statusLabel = new Label(dialogArea, SWT.NONE);
|
||||
statusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
SwtConnect.connect(statusLabel, model.getStatus());
|
||||
|
||||
viewer.setInput(model);
|
||||
return dialogArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureShell(Shell shell) {
|
||||
super.configureShell(shell);
|
||||
|
||||
Control control = fTextEditor.getAdapter(Control.class);
|
||||
if (control != null) {
|
||||
//Set size relative to editor's size.
|
||||
Point size = new Point(control.getBounds().width/3, control.getBounds().height/2);
|
||||
shell.setSize(size);
|
||||
if (alignRight) {
|
||||
shell.setLocation(control.toDisplay(control.getBounds().width - shell.getSize().x, control.getLocation().y));
|
||||
} else {
|
||||
//centered on the editor
|
||||
shell.setLocation(control.toDisplay(control.getBounds().width/3, control.getBounds().height/4));
|
||||
}
|
||||
} else {
|
||||
// fallback
|
||||
shell.setSize(280, 300);
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Determines the graphical area covered by the given text region.
|
||||
// *
|
||||
// * @param region the region whose graphical extend must be computed
|
||||
// * @return the graphical extend of the given region
|
||||
// */
|
||||
// private Rectangle computeArea(IRegion region) {
|
||||
//
|
||||
// int start= 0;
|
||||
// int end= 0;
|
||||
//
|
||||
// IRegion widgetRegion= modelRange2WidgetRange(region);
|
||||
// if (widgetRegion != null) {
|
||||
// start= widgetRegion.getOffset();
|
||||
// end= widgetRegion.getOffset() + widgetRegion.getLength();
|
||||
// }
|
||||
//
|
||||
// StyledText styledText= fTextEditor.getTextWidget();
|
||||
// Rectangle bounds;
|
||||
// if (end > 0 && start < end)
|
||||
// bounds= styledText.getTextBounds(start, end - 1);
|
||||
// else {
|
||||
// Point loc= styledText.getLocationAtOffset(start);
|
||||
// bounds= new Rectangle(loc.x, loc.y, 0, styledText.getLineHeight(start));
|
||||
// }
|
||||
//
|
||||
// Rectangle clientArea= styledText.getClientArea();
|
||||
// Geometry.moveInside(bounds, clientArea);
|
||||
// return bounds;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.springframework.ide.eclipse.boot.util.Log;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression.AsyncMode;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet;
|
||||
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public class GotoSymbolDialogModel {
|
||||
|
||||
private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder");
|
||||
private static void debug(String string) {
|
||||
if (DEBUG) {
|
||||
System.out.println(string);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface OKHandler {
|
||||
/**
|
||||
* Called by the ui to perform the dialog's action. The dialog will be
|
||||
* closed by the ui this returns true, otherwise it remains open.
|
||||
*/
|
||||
boolean performOk(SymbolInformation selection);
|
||||
}
|
||||
|
||||
private static final OKHandler DEFAULT_OK_HANDLER = (selection) -> true;
|
||||
|
||||
private SymbolsProvider[] symbolsProviders;
|
||||
private final LiveVariable<String> status = new LiveVariable<>();
|
||||
private int currentSymbolsProviderIndex;
|
||||
private final LiveVariable<SymbolsProvider> currentSymbolsProvider = new LiveVariable<>(null);
|
||||
private final LiveVariable<String> searchBox = new LiveVariable<>("");
|
||||
private final ObservableSet<SymbolInformation> unfilteredSymbols = new ObservableSet<SymbolInformation>(ImmutableSet.of(), AsyncMode.ASYNC, AsyncMode.SYNC) {
|
||||
//Note: fetching is 'slow' so is done asynchronously
|
||||
{
|
||||
setRefreshDelay(100);
|
||||
dependsOn(searchBox);
|
||||
dependsOn(currentSymbolsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImmutableSet<SymbolInformation> compute() {
|
||||
status.setValue("Fetching symbols...");
|
||||
try {
|
||||
SymbolsProvider sp = currentSymbolsProvider.getValue();
|
||||
if (sp!=null) {
|
||||
debug("Fetching "+sp.getName());
|
||||
String query = searchBox.getValue();
|
||||
debug("Fetching symbols... from symbol provider, for '"+query+"'");
|
||||
Collection<SymbolInformation> fetched = sp.fetchFor(query);
|
||||
if (keyBindings==null) {
|
||||
status.setValue(sp.getName());
|
||||
} else {
|
||||
status.setValue("Press ["+keyBindings+"] for "+nextSymbolsProvider().getName());
|
||||
}
|
||||
return ImmutableSet.copyOf(fetched);
|
||||
} else {
|
||||
status.setValue("No symbol provider");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
status.setValue(ExceptionUtil.getMessage(e));
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
private SymbolsProvider nextSymbolsProvider() {
|
||||
int nextIndex = (currentSymbolsProviderIndex + 1)%symbolsProviders.length;
|
||||
return symbolsProviders[nextIndex];
|
||||
}
|
||||
};
|
||||
|
||||
private ObservableSet<SymbolInformation> filteredSymbols = new ObservableSet<SymbolInformation>() {
|
||||
//Note: filtering is 'fast' so is done synchronously
|
||||
{
|
||||
dependsOn(searchBox);
|
||||
dependsOn(unfilteredSymbols);
|
||||
}
|
||||
|
||||
private boolean containsCharacters(char[] symbolChars, char[] queryChars) {
|
||||
int symbolindex = 0;
|
||||
int queryindex = 0;
|
||||
|
||||
while (queryindex < queryChars.length && symbolindex < symbolChars.length) {
|
||||
if (symbolChars[symbolindex] == queryChars[queryindex]) {
|
||||
queryindex++;
|
||||
}
|
||||
symbolindex++;
|
||||
}
|
||||
|
||||
return queryindex == queryChars.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImmutableSet<SymbolInformation> compute() {
|
||||
char[] query = searchBox.getValue().toCharArray();
|
||||
ImmutableSet.Builder<SymbolInformation> builder = ImmutableSet.builder();
|
||||
unfilteredSymbols.getValues().stream().filter(sym -> containsCharacters(sym.getName().toCharArray(), query)).forEach(builder::add);
|
||||
return builder.build();
|
||||
}
|
||||
};
|
||||
|
||||
private String keyBindings;
|
||||
private OKHandler okHandler = DEFAULT_OK_HANDLER;
|
||||
|
||||
public GotoSymbolDialogModel(String keyBindings, SymbolsProvider... symbolsProviders) {
|
||||
this.keyBindings = keyBindings;
|
||||
Assert.isLegal(symbolsProviders.length>0);
|
||||
this.symbolsProviders = symbolsProviders;
|
||||
this.currentSymbolsProviderIndex = 0;
|
||||
this.currentSymbolsProvider.setValue(symbolsProviders[0]);
|
||||
if (DEBUG) {
|
||||
searchBox.addListener((e, v) -> {
|
||||
debug("searchBox = "+v);
|
||||
});
|
||||
unfilteredSymbols.addListener((e, v) -> debug("raw = "+summary(filteredSymbols.getValues())));
|
||||
filteredSymbols.addListener((e, v) -> debug("filtered = "+summary(filteredSymbols.getValues())));
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> summary(ImmutableSet<SymbolInformation> values) {
|
||||
return values.stream().map(SymbolInformation::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public ObservableSet<SymbolInformation> getSymbols() {
|
||||
return filteredSymbols;
|
||||
}
|
||||
|
||||
public LiveVariable<String> getSearchBox() {
|
||||
return searchBox;
|
||||
}
|
||||
|
||||
public LiveExpression<String> getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public synchronized void toggleSymbolsProvider() {
|
||||
currentSymbolsProviderIndex = (currentSymbolsProviderIndex+1)%symbolsProviders.length;
|
||||
currentSymbolsProvider.setValue(symbolsProviders[currentSymbolsProviderIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an ok handler. The handler is meant to be called by the UI when user request to
|
||||
* execute the dialogs action on its current selection. For example, by pressing 'ENTER'
|
||||
* key, or by double-clicking an element.
|
||||
* <p>
|
||||
* If 'okHandler' returns 'true' then the dialog is closed. Otherwise it remains open.
|
||||
*/
|
||||
public GotoSymbolDialogModel setOkHandler(OKHandler okHandler) {
|
||||
this.okHandler = okHandler == null ? DEFAULT_OK_HANDLER : okHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean performOk(SymbolInformation selection) {
|
||||
return this.okHandler.performOk(selection);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.lsp4e.LSPEclipseUtils;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor.LSPDocumentInfo;
|
||||
import org.eclipse.lsp4j.DocumentSymbolParams;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.handlers.HandlerUtil;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* SymbolsProvider that only looks for symbols in current file using the LSP 'document/symbols' api.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class InFileSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
private LSPDocumentInfo info;
|
||||
|
||||
public InFileSymbolsProvider(LSPDocumentInfo target) {
|
||||
super();
|
||||
this.info = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> fetchFor(String query) throws Exception {
|
||||
DocumentSymbolParams params = new DocumentSymbolParams(
|
||||
new TextDocumentIdentifier(info.getFileUri().toString()));
|
||||
CompletableFuture<List<? extends SymbolInformation>> symbolsFuture = info.getLanguageClient()
|
||||
.getTextDocumentService().documentSymbol(params);
|
||||
List<? extends SymbolInformation> symbols = symbolsFuture.get();
|
||||
Thread.sleep(2000);
|
||||
return symbols == null ? ImmutableList.of() : ImmutableList.copyOf(symbols);
|
||||
}
|
||||
|
||||
public static SymbolsProvider createFor(ITextEditor textEditor) {
|
||||
Collection<LSPDocumentInfo> infos = LanguageServiceAccessor.getLSPDocumentInfosFor(
|
||||
LSPEclipseUtils.getDocument(textEditor),
|
||||
capabilities -> Boolean.TRUE.equals(capabilities.getDocumentSymbolProvider()));
|
||||
if (infos.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// TODO maybe consider better strategy such as iterating on all LS until we have a good result
|
||||
LSPDocumentInfo info = infos.iterator().next();
|
||||
if (info!=null) {
|
||||
return new InFileSymbolsProvider(info);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Symbols in File";
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.handlers.HandlerUtil;
|
||||
import org.springframework.ide.eclipse.boot.util.Log;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class InWorkspaceSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
private static final Duration TIMEOUT = Duration.ofSeconds(2);
|
||||
|
||||
private List<LanguageServer> languageServers;
|
||||
|
||||
public InWorkspaceSymbolsProvider(List<LanguageServer> languageServers) {
|
||||
this.languageServers = languageServers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Symbols in Workspace";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> fetchFor(String query) throws Exception {
|
||||
//TODO: if we want decent support for multiple language servers...
|
||||
// consider changing SymbolsProvider api and turning the stuff in here into something producing a
|
||||
// Flux<Collection<SymbolInformation>>
|
||||
// This will help in
|
||||
// - supporting cancelation
|
||||
// - executing multiple requests to different servers in parallel.
|
||||
// - producing results per server so don't have to wait for one slow server to see the rest.
|
||||
//However it will also add complexity to the code that consumes this and at this time we only
|
||||
// really use this with a single language server anyways.
|
||||
ImmutableList.Builder<SymbolInformation> allSymbols = ImmutableList.builder();
|
||||
for (LanguageServer server : this.languageServers) {
|
||||
try {
|
||||
WorkspaceSymbolParams params = new WorkspaceSymbolParams(query);
|
||||
List<? extends SymbolInformation> symbolsFuture =
|
||||
server.getWorkspaceService().symbol(params)
|
||||
.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
|
||||
allSymbols.addAll(symbolsFuture);
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
return allSymbols.build();
|
||||
}
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(ExecutionEvent event) {
|
||||
IEditorPart part = HandlerUtil.getActiveEditor(event);
|
||||
IResource resource = null;
|
||||
if (part != null && part.getEditorInput() != null) {
|
||||
resource = part.getEditorInput().getAdapter(IResource.class);
|
||||
} else {
|
||||
IStructuredSelection selection = HandlerUtil.getCurrentStructuredSelection(event);
|
||||
if (selection.isEmpty() || !(selection.getFirstElement() instanceof IAdaptable)) {
|
||||
return null;
|
||||
}
|
||||
IAdaptable adaptable = (IAdaptable) selection.getFirstElement();
|
||||
resource = adaptable.getAdapter(IResource.class);
|
||||
}
|
||||
if (resource!=null) {
|
||||
return createFor(resource.getProject());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(IProject project) {
|
||||
List<LanguageServer> languageServers = LanguageServiceAccessor.getLanguageServers(project,
|
||||
capabilities -> Boolean.TRUE.equals(capabilities.getWorkspaceSymbolProvider()));
|
||||
if (!languageServers.isEmpty()) {
|
||||
return new InWorkspaceSymbolsProvider(languageServers);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
|
||||
/**
|
||||
* An SymbolsProvider can fetch symbols from a service (typically, a language server
|
||||
* operation is used to fetch symbol data. This operation may be slow and should be
|
||||
* called only from a background job.
|
||||
*/
|
||||
public interface SymbolsProvider {
|
||||
String getName();
|
||||
Collection<SymbolInformation> fetchFor(String query) throws Exception;
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Rogue Wave Software Inc. and others.
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Michał Niewrzał (Rogue Wave Software Inc.) - initial implementation
|
||||
* Kris De Volder (Pivotal) - copied and adapted from org.eclipse.lsp4e.operations.symbols.LSPSymbolInFileDialog
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.handlers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.commands.AbstractHandler;
|
||||
import org.eclipse.core.commands.Command;
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.commands.ExecutionException;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.bindings.TriggerSequence;
|
||||
import org.eclipse.lsp4e.LSPEclipseUtils;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor.LSPDocumentInfo;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.IWorkbenchPart;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.handlers.HandlerUtil;
|
||||
import org.eclipse.ui.keys.IBindingService;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.GotoSymbolDialog;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.GotoSymbolDialogModel;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.InFileSymbolsProvider;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.InWorkspaceSymbolsProvider;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class GotoSymbolHandler extends AbstractHandler {
|
||||
|
||||
private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder");
|
||||
|
||||
private static void debug(String string) {
|
||||
if (DEBUG) {
|
||||
System.out.println(string);
|
||||
}
|
||||
}
|
||||
private static GotoSymbolDialogModel currentDialog = null;
|
||||
|
||||
public GotoSymbolHandler() {
|
||||
debug("Creating GotoSymbolHandler");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(ExecutionEvent event) throws ExecutionException {
|
||||
debug(">>>GotoSymbolHandler.execute");
|
||||
if (currentDialog!=null) {
|
||||
debug("GotoSymbolDialog already open: send 'toggle' signal");
|
||||
currentDialog.toggleSymbolsProvider();
|
||||
} else {
|
||||
IEditorPart part = HandlerUtil.getActiveEditor(event);
|
||||
if (part instanceof ITextEditor) {
|
||||
final Shell shell = HandlerUtil.getActiveShell(event);
|
||||
final ITextEditor textEditor = (ITextEditor) part;
|
||||
|
||||
GotoSymbolDialogModel model = new GotoSymbolDialogModel(getKeybindings(event), InFileSymbolsProvider.createFor(textEditor), InWorkspaceSymbolsProvider.createFor(event))
|
||||
.setOkHandler(symbolInformation -> {
|
||||
if (symbolInformation!=null) {
|
||||
Location location = symbolInformation.getLocation();
|
||||
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||
LSPEclipseUtils.openInEditor(location, page);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
GotoSymbolDialog dialog = new GotoSymbolDialog(shell, textEditor, model, /*alignRight*/ false);
|
||||
currentDialog = model;
|
||||
dialog.open();
|
||||
debug("GotoSymbolDialog opened");
|
||||
dialog.getShell().addDisposeListener(de -> {
|
||||
debug("GotoSymbolDialog closed!");
|
||||
currentDialog = null;
|
||||
});
|
||||
}
|
||||
debug("<<<GotoSymbolHandler.execute");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getKeybindings(ExecutionEvent event) {
|
||||
Command invokingCommand = event.getCommand();
|
||||
IBindingService service = PlatformUI.getWorkbench().getService(IBindingService.class);
|
||||
TriggerSequence[] bindings = service.getActiveBindingsFor(invokingCommand.getId());
|
||||
if (bindings!=null && bindings.length>0) {
|
||||
return bindings[0].toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
boolean r = _isEnabled();
|
||||
return r;
|
||||
}
|
||||
public boolean _isEnabled() {
|
||||
IWorkbenchPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart();
|
||||
if (part instanceof ITextEditor) {
|
||||
debug("activePart instanceof ITextEditor");
|
||||
List<LSPDocumentInfo> infos = LanguageServiceAccessor.getLSPDocumentInfosFor(
|
||||
LSPEclipseUtils.getDocument((ITextEditor) part),
|
||||
(capabilities) -> Boolean.TRUE.equals(capabilities.getDocumentSymbolProvider()));
|
||||
return !infos.isEmpty();
|
||||
}
|
||||
debug("activePart not ITextEditor: "+part);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.util;
|
||||
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.UIValueListener;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
|
||||
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
|
||||
|
||||
/**
|
||||
* Static helper methods for attaching LiveExps to SWT widgets.
|
||||
*/
|
||||
public class SwtConnect {
|
||||
|
||||
public static void connect(Text widget, LiveVariable<String> model) {
|
||||
ModifyListener widgetListener = (ModifyEvent e) -> {
|
||||
model.setValue(widget.getText());
|
||||
};
|
||||
ValueListener<String> modelListener = new UIValueListener<String>() {
|
||||
@Override
|
||||
protected void uiGotValue(LiveExpression<String> exp, String value) {
|
||||
String newText = model.getValue();
|
||||
if (newText==null) {
|
||||
newText = "";
|
||||
}
|
||||
String oldText = widget.getText();
|
||||
if (!newText.equals(oldText)) {
|
||||
widget.setText(newText);
|
||||
}
|
||||
}
|
||||
};
|
||||
widget.addModifyListener(widgetListener);
|
||||
model.addListener(modelListener);
|
||||
widget.addDisposeListener(e -> {
|
||||
model.removeListener(modelListener);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static void connect(Label widget, LiveExpression<String> model) {
|
||||
ValueListener<String> modelListener = new UIValueListener<String>() {
|
||||
@Override
|
||||
protected void uiGotValue(LiveExpression<String> exp, String value) {
|
||||
String newText = model.getValue();
|
||||
if (newText==null) {
|
||||
newText = "";
|
||||
}
|
||||
widget.setText(newText);
|
||||
}
|
||||
};
|
||||
model.addListener(modelListener);
|
||||
widget.addDisposeListener(xx -> model.removeListener(modelListener));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user