diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java index 3701a7516..04c380153 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java @@ -37,15 +37,16 @@ import reactor.core.publisher.Mono; public class InProjectSymbolsProvider implements SymbolsProvider { public static InProjectSymbolsProvider createFor(LiveExpression project) { - LiveExpression> languageServers = project.apply(p -> - p == null + LiveExpression> languageServers = project.apply(p -> { + System.out.println("project = "+(p==null?null:p.getName())); + return p == null ? ImmutableList.of() : LanguageServiceAccessor.getLanguageServers( project.getValue(), capabilities -> Boolean.TRUE.equals(capabilities.getWorkspaceSymbolProvider()), true - ) - ); + ); + }); return new InProjectSymbolsProvider(languageServers::getValue, project::getValue); } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SelectionTracker.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SelectionTracker.java new file mode 100644 index 000000000..40e1c91de --- /dev/null +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SelectionTracker.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2020 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 + * https://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.HashMap; +import java.util.Map; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.ISelectionService; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.springframework.ide.eclipse.boot.dash.model.AbstractDisposable; +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.util.Log; + +public class SelectionTracker extends AbstractDisposable { + + private static Map INSTANCES = new HashMap<>(); + + public static synchronized SelectionTracker getInstance(IWorkbenchWindow wbw) { + return INSTANCES.computeIfAbsent(wbw, _wbw -> { + return new SelectionTracker(wbw); + }); + } + + private static synchronized void disposeInstance(IWorkbenchWindow wbw) { + SelectionTracker removed = INSTANCES.remove(wbw); + if (removed!=null) { + removed.dispose(); + } + } + + private final LiveVariable currentResource = new LiveVariable<>(); + public final LiveExpression currentProject = currentResource.apply(r -> r==null ? null : r.getProject()); + + private SelectionTracker(IWorkbenchWindow wbw) { + ISelectionService selectionService = wbw.getSelectionService(); + ISelectionListener selectionListener = new ISelectionListener() { + + @Override + public void selectionChanged(IWorkbenchPart arg0, ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + Object element = ss.getFirstElement(); + IResource rsrc = getResource(element); + if (rsrc!=null) { + currentResource.setValue(rsrc); + } + } else if (selection instanceof ITextSelection) { + //Let's assume the selection is in the active editor + try { + IEditorPart editor = wbw.getActivePage().getActiveEditor(); + if (editor!=null) { + IEditorInput input = editor.getEditorInput(); + currentResource.setValue(input.getAdapter(IResource.class)); + } + } catch (Exception e) { + Log.log(e); + } + } + } + + private IResource getResource(Object element) { + if (element instanceof IResource) { + return (IResource) element; + } else if (element instanceof IAdaptable) { + return ((IAdaptable) element).getAdapter(IResource.class); + } + return null; + } + }; + selectionService.addSelectionListener(selectionListener); + onDispose(de -> { + selectionService.removeSelectionListener(selectionListener); + }); + wbw.getShell().addDisposeListener(de -> { + disposeInstance(wbw); + }); + + //Code below tries to determine the 'initial' selection. + //Unfortunately, doesn't work. Mostly just getting null here, seems to be no way to get + // 'initial' selection reliably. + ISelection initialSelection = selectionService.getSelection(); + if (initialSelection!=null) { + selectionListener.selectionChanged(null, initialSelection); + } + } + + public LiveExpression currentResource() { + return currentResource; + } +} diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolsProviders.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolsProviders.java new file mode 100644 index 000000000..a8b59838a --- /dev/null +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolsProviders.java @@ -0,0 +1,5 @@ +package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs; + +public class SymbolsProviders { + +} diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsView.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsView.java index c0ee9691d..25e013939 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsView.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsView.java @@ -14,24 +14,15 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.Platform; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.ISelectionListener; -import org.eclipse.ui.ISelectionService; +import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.springframework.ide.eclipse.boot.dash.BootDashActivator; import org.springframework.ide.eclipse.boot.dash.views.sections.ViewPartWithSections; @@ -58,10 +49,7 @@ public class SpringSymbolsView extends ViewPartWithSections { */ private static final boolean ENABLE_SCROLLING = false; - private final SpringSymbolsViewModel model = new SpringSymbolsViewModel(); - { - model.gotoSymbols.setOkHandler(GotoSymbolDialogModel.OPEN_IN_EDITOR_OK_HANDLER); - } + private SpringSymbolsViewModel model; Action a = new Action("New View", BootDashActivator.getImageDescriptor("icons/add_target.png")) { @Override @@ -77,42 +65,7 @@ public class SpringSymbolsView extends ViewPartWithSections { } }; - private ISelectionListener selectionListener = new ISelectionListener() { - - @Override - public void selectionChanged(IWorkbenchPart arg0, ISelection selection) { - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - Object element = ss.getFirstElement(); - IResource rsrc = getResource(element); - if (rsrc!=null) { - model.currentResource.setValue(rsrc); - } - } else if (selection instanceof ITextSelection) { - //Let's assume the selection is in the active editor - try { - IEditorPart editor = getSite().getWorkbenchWindow().getActivePage().getActiveEditor(); - if (editor!=null) { - IEditorInput input = editor.getEditorInput(); - model.currentResource.setValue(input.getAdapter(IResource.class)); - } - } catch (Exception e) { - Log.log(e); - } - } - } - - private IResource getResource(Object element) { - if (element instanceof IResource) { - return (IResource) element; - } else if (element instanceof IAdaptable) { - return ((IAdaptable) element).getAdapter(IResource.class); - } - return null; - } - }; - - private List disposables = new ArrayList<>(); + private List disposables = new ArrayList<>(); //TODO: Remove... unused? public SpringSymbolsView() { super(ENABLE_SCROLLING); @@ -142,11 +95,6 @@ public class SpringSymbolsView extends ViewPartWithSections { }) ); sections.add(new GotoSymbolSection(this, model.gotoSymbols).enableStatusLine(false)); - ISelectionService selectitonService = getSite().getWorkbenchWindow().getSelectionService(); - selectitonService.addSelectionListener(selectionListener); - this.disposables.add(() -> { - selectitonService.removeSelectionListener(selectionListener); - }); return sections; } @@ -185,4 +133,11 @@ public class SpringSymbolsView extends ViewPartWithSections { super.dispose(); } + @Override + public void init(IViewSite site) throws PartInitException { + super.init(site); + model = new SpringSymbolsViewModel(getSite().getWorkbenchWindow()); + model.gotoSymbols.setOkHandler(GotoSymbolDialogModel.OPEN_IN_EDITOR_OK_HANDLER); + } + } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsViewModel.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsViewModel.java index a44be3389..6f52fbc8c 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsViewModel.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/view/SpringSymbolsViewModel.java @@ -12,25 +12,33 @@ package org.springframework.tooling.ls.eclipse.gotosymbol.view; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.ui.IWorkbenchWindow; 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.InProjectSymbolsProvider; import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.InWorkspaceSymbolsProvider; +import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.SelectionTracker; import org.springframework.tooling.ls.eclipse.gotosymbol.favourites.FavouritesPreference; import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; public class SpringSymbolsViewModel { + + public final SelectionTracker currentSelection; + public final GotoSymbolDialogModel gotoSymbols; - public final LiveVariable currentResource = new LiveVariable<>(); - public final LiveExpression currentProject = currentResource.apply(r -> r==null ? null : r.getProject()); - public final GotoSymbolDialogModel gotoSymbols = new GotoSymbolDialogModel(null, - InWorkspaceSymbolsProvider.createFor(currentProject::getValue), - InProjectSymbolsProvider.createFor(currentProject), - InFileSymbolsProvider.createFor(currentResource) - ) - .setFavourites(FavouritesPreference.INSTANCE); - { - gotoSymbols.unfilteredSymbols.dependsOn(currentProject); + public SpringSymbolsViewModel(IWorkbenchWindow wbw) { + currentSelection = SelectionTracker.getInstance(wbw); + LiveExpression currentResource = currentSelection.currentResource(); + LiveExpression currentProject = currentSelection.currentProject; + gotoSymbols = new GotoSymbolDialogModel(null, + InWorkspaceSymbolsProvider.createFor(currentProject::getValue), + InProjectSymbolsProvider.createFor(currentProject), + InFileSymbolsProvider.createFor(currentResource) + ) + .setFavourites(FavouritesPreference.INSTANCE); + { + gotoSymbols.unfilteredSymbols.dependsOn(currentResource); + gotoSymbols.unfilteredSymbols.dependsOn(currentProject); + } } }