Minimal UI to manage goto symbol 'Favourites'

This commit is contained in:
Kris De Volder
2020-06-09 15:22:36 -07:00
parent 05fe3272a3
commit 1c09e8e594
7 changed files with 168 additions and 13 deletions

View File

@@ -20,7 +20,9 @@ Require-Bundle: org.eclipse.ui,
org.springsource.ide.eclipse.commons.core;bundle-version="3.9.2",
io.projectreactor.reactor-core;bundle-version="3.0.7",
org.reactivestreams.reactive-streams;bundle-version="1.0.0",
org.springframework.ide.eclipse.boot.dash
org.springframework.ide.eclipse.boot.dash,
org.springsource.ide.eclipse.commons.frameworks.core,
org.springframework.ide.eclipse.boot
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Activator: org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin
Bundle-ActivationPolicy: lazy

View File

@@ -15,6 +15,8 @@ import org.osgi.framework.BundleContext;
public class GotoSymbolPlugin extends AbstractUIPlugin {
public static final String ID = "org.springframework.tooling.ls.eclipse.gotosymbol";
private static GotoSymbolPlugin instance;
public GotoSymbolPlugin() {

View File

@@ -30,7 +30,6 @@ public class GotoSymbolDialog extends PopupDialog implements IPageWithSections {
private static final Point DEFAULT_SIZE = new Point(280, 300);
private GotoSymbolDialogModel model;
private final GotoSymbolSection content;
private ITextEditor fTextEditor;
@@ -49,7 +48,6 @@ public class GotoSymbolDialog extends PopupDialog implements IPageWithSections {
// 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.content = new GotoSymbolSection(this, model);
this.alignRight = alignRight;
create();

View File

@@ -26,6 +26,7 @@ import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin;
import org.springframework.tooling.ls.eclipse.gotosymbol.favourites.FavouritesPreference;
import org.springsource.ide.eclipse.commons.core.util.FuzzyMatcher;
import org.springsource.ide.eclipse.commons.core.util.StringUtil;
import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression.AsyncMode;
@@ -196,7 +197,7 @@ public class GotoSymbolDialogModel {
private String keyBindings;
private OKHandler okHandler = DEFAULT_OK_HANDLER;
private Favourite[] favourites = null;
private FavouritesPreference favourites = null;
public GotoSymbolDialogModel(String keyBindings, SymbolsProvider... symbolsProviders) {
this.keyBindings = keyBindings;
@@ -213,12 +214,12 @@ public class GotoSymbolDialogModel {
}
}
public GotoSymbolDialogModel setFavourites(Favourite... favourites) {
public GotoSymbolDialogModel setFavourites(FavouritesPreference favourites) {
this.favourites = favourites;
return this;
}
public Favourite[] getFavourites() {
public FavouritesPreference getFavourites() {
return favourites;
}

View File

@@ -14,12 +14,17 @@ package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.text.BadLocationException;
@@ -62,7 +67,9 @@ import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.GotoSymbolDialogModel.Favourite;
import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.GotoSymbolDialogModel.Match;
import org.springframework.tooling.ls.eclipse.gotosymbol.favourites.FavouritesPreference;
import org.springsource.ide.eclipse.commons.core.util.FuzzyMatcher;
import org.springsource.ide.eclipse.commons.core.util.StringUtil;
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.ui.Disposable;
@@ -295,13 +302,16 @@ public class GotoSymbolSection extends WizardPageSection {
viewer.setInput(model);
}
private void createFavouritesPulldown(Composite parent, Favourite[] favourites, LiveVariable<String> searchBox) {
private void createFavouritesPulldown(Composite parent, FavouritesPreference favouritePrefs, LiveVariable<String> searchBox) {
Button btn = new Button(parent, SWT.ARROW | SWT.DOWN);
btn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
Menu menu = new Menu(btn);
// create item for each of the known favourites
Favourite[] favourites = favouritePrefs.getFavourites();
Set<String> existingFavs = new HashSet<>();
for (Favourite f : favourites) {
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText(f.toString());
@@ -310,7 +320,40 @@ public class GotoSymbolSection extends WizardPageSection {
searchBox.setValue(f.query);
}
});
existingFavs.add(f.query);
}
//separator
new MenuItem(menu, SWT.SEPARATOR);
String currentSearch = searchBox.getValue();
if (StringUtil.hasText(currentSearch)) {
if (!existingFavs.contains(currentSearch)) {
//create a 'add favourite' menu item
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Add Favourite...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = inputDialog("Add '"+currentSearch+"' as a favourite", "Name:", "");
if (StringUtil.hasText(name)) {
favouritePrefs.add(name, currentSearch);
}
}
});
} else { // the currentSearch is already a favourite
//create a 'remove favourite' menu item
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Remove '"+currentSearch+"' Favourite");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
favouritePrefs.remove(currentSearch);
}
});
}
}
Point loc = btn.getLocation();
Rectangle rect = btn.getBounds();
Point mLoc = new Point(loc.x-1, loc.y+rect.height);
@@ -320,6 +363,20 @@ public class GotoSymbolSection extends WizardPageSection {
});
}
private String inputDialog(String dialogTitle, String prompt, String defaultValue) {
AtomicReference<String> result = new AtomicReference<>();
owner.getShell().getDisplay().syncExec(new Runnable() {
public void run() {
InputDialog dlg = new InputDialog(owner.getShell(), dialogTitle, prompt, defaultValue, null);
int code = dlg.open();
if (code==IDialogConstants.OK_ID) {
result.set(dlg.getValue());
}
}
});
return result.get();
}
private void installWidgetListeners(Text pattern, TreeViewer list) {
pattern.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {

View File

@@ -0,0 +1,99 @@
/*******************************************************************************
* Copyright (c) 2020 Pivotal Software, 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 Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.tooling.ls.eclipse.gotosymbol.favourites;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.MenuItem;
import org.springframework.ide.eclipse.boot.pstore.IPropertyStore;
import org.springframework.ide.eclipse.boot.pstore.PropertyStoreApi;
import org.springframework.ide.eclipse.boot.pstore.PropertyStores;
import org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin;
import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.GotoSymbolDialogModel.Favourite;
import org.springsource.ide.eclipse.commons.core.util.StringUtil;
import org.springsource.ide.eclipse.commons.livexp.util.Log;
public class FavouritesPreference {
/**
* The singleton 'Production' instance of {@link FavouritesPreference}. This stores/reads favourites to/from
* the Eclipse preference store for {@link GotoSymbolPlugin}.
*/
public static final FavouritesPreference INSTANCE = new FavouritesPreference(
PropertyStores.backedBy(GotoSymbolPlugin.getInstance().getPreferenceStore())
);
public static final Favourite[] DEFAULT = {
new Favourite("Request Mappings", "@/"),
new Favourite("Beans", "@+"),
new Favourite("All Spring Elements", "@")
};
private static final String KEY = "favourites";
private static final String[] NO_STRINGS = {};
private PropertyStoreApi prefs;
public FavouritesPreference(IPropertyStore backingStore) {
this.prefs = new PropertyStoreApi(backingStore);
}
public Favourite[] getFavourites() {
try {
String[] strings = prefs.get(KEY, NO_STRINGS);
if (strings!=null && strings.length>0) {
Favourite[] favs = new Favourite[strings.length/2];
for (int i = 0; i < strings.length; i+=2) {
favs[i/2] = new Favourite(strings[i], strings[i+1]);
}
return favs;
}
} catch (Exception e) {
Log.log(e);
}
return DEFAULT;
}
public void setFavourites(Favourite[] favourites) {
try {
String[] strings = new String[favourites.length*2];
for (int i = 0; i < strings.length; i+=2) {
Favourite fav = favourites[i/2];
strings[i] = fav.name;
strings[i+1] = fav.query;
}
prefs.put(KEY, strings);
} catch (Exception e) {
Log.log(e);
}
}
public void add(String name, String currentSearch) {
Favourite[] oldFavs = getFavourites();
Favourite[] newFavs = new Favourite[oldFavs.length+1];
for (int i = 0; i < oldFavs.length; i++) {
newFavs[i] = oldFavs[i];
}
newFavs[oldFavs.length] = new Favourite(name, currentSearch);
setFavourites(newFavs);
}
public void remove(String currentSearch) {
List<Favourite> retain = new ArrayList<>();
for (Favourite favourite : getFavourites()) {
if (!favourite.query.equals(currentSearch)) {
retain.add(favourite);
}
}
setFavourites(retain.toArray(new Favourite[retain.size()]));
}
}

View File

@@ -16,7 +16,7 @@ import org.springframework.tooling.ls.eclipse.gotosymbol.dialogs.GotoSymbolDialo
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.GotoSymbolDialogModel.Favourite;
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;
@@ -29,11 +29,7 @@ public class SpringSymbolsViewModel {
InProjectSymbolsProvider.createFor(currentProject),
InFileSymbolsProvider.createFor(currentResource)
)
.setFavourites(
new Favourite("Request Mappings", "@/"),
new Favourite("Beans", "@+"),
new Favourite("All Spring Elements", "@")
);
.setFavourites(FavouritesPreference.INSTANCE);
{
gotoSymbols.unfilteredSymbols.dependsOn(currentProject);
}