Shared selection tracking for GotoSymbolsView...
... and a fix for https://www.pivotaltracker.com/story/show/173266410
This commit is contained in:
@@ -37,15 +37,16 @@ import reactor.core.publisher.Mono;
|
||||
public class InProjectSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
public static InProjectSymbolsProvider createFor(LiveExpression<IProject> project) {
|
||||
LiveExpression<List<LanguageServer>> languageServers = project.apply(p ->
|
||||
p == null
|
||||
LiveExpression<List<LanguageServer>> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<IWorkbenchWindow, SelectionTracker> 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<IResource> currentResource = new LiveVariable<>();
|
||||
public final LiveExpression<IProject> 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<IResource> currentResource() {
|
||||
return currentResource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
public class SymbolsProviders {
|
||||
|
||||
}
|
||||
@@ -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<Disposable> disposables = new ArrayList<>();
|
||||
private List<Disposable> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<IResource> currentResource = new LiveVariable<>();
|
||||
public final LiveExpression<IProject> 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<IResource> currentResource = currentSelection.currentResource();
|
||||
LiveExpression<IProject> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user