mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Bug 104792 - Content proposal filtering feature.
This commit is contained in:
parent
c1c8415408
commit
e0a9f12895
13 changed files with 594 additions and 44 deletions
|
@ -121,5 +121,12 @@
|
|||
id="org.eclipse.cdt.ui.tests.DOMAST.DOMAST.IncludeStatementFilter">
|
||||
</filter>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.ui.ProposalFilter">
|
||||
<ProposalFilter
|
||||
class="org.eclipse.cdt.ui.tests.text.contentassist.TestProposalFilter"
|
||||
id="org.eclipse.cdt.ui.tests.TestProposalFilter"
|
||||
name="Testing Completion Filter"/>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package org.eclipse.cdt.ui.tests.text.contentassist;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
|
||||
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil.ComboState;
|
||||
import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* This test covers the convenience methods
|
||||
* in org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil
|
||||
*/
|
||||
public class ProposalFilterPreferencesTest extends TestCase {
|
||||
|
||||
public void testPreferences() {
|
||||
// Check that the test filter is among the filternames
|
||||
String[] filterNames = ProposalFilterPreferencesUtil.getProposalFilterNames();
|
||||
int index = -1 ;
|
||||
for (int i = 0; i < filterNames.length; i++) {
|
||||
String name = filterNames[i];
|
||||
if (name.equals("Testing Completion Filter")) {
|
||||
index = i ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
assertTrue("Did not find expected filter!", index>=0);
|
||||
|
||||
// Set the preference to the tested filter
|
||||
IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore();
|
||||
String filterComboStateString = store.getString(ContentAssistPreference.PROPOSALS_FILTER);
|
||||
ProposalFilterPreferencesUtil.ComboState state = ProposalFilterPreferencesUtil.getComboState(filterComboStateString);
|
||||
StringBuffer newStateText = new StringBuffer();
|
||||
newStateText.append(index+1); // First entry is always the <Default Filter>, index+1 must be selected
|
||||
for (int i = 0; i < state.items.length; i++) {
|
||||
String item = state.items[i];
|
||||
newStateText.append(";");
|
||||
newStateText.append(item);
|
||||
}
|
||||
store.setValue(ContentAssistPreference.PROPOSALS_FILTER, newStateText.toString());
|
||||
|
||||
// Now we can test preferred filter retrieval:
|
||||
IConfigurationElement preferredElement = ProposalFilterPreferencesUtil.getPreferredFilterElement();
|
||||
String extensionId = preferredElement.getAttribute("id");
|
||||
assertNotNull("Configuration element was not found!", extensionId);
|
||||
assertEquals("Unexpected element id", "org.eclipse.cdt.ui.tests.TestProposalFilter", extensionId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.eclipse.cdt.ui.tests.text.contentassist;
|
||||
|
||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
|
||||
|
||||
/**
|
||||
* Dummy filter implementation for testing purposes
|
||||
*/
|
||||
public class TestProposalFilter implements IProposalFilter {
|
||||
|
||||
/**
|
||||
* This dummy filter method will return the original proposals unmodified.
|
||||
*/
|
||||
public ICCompletionProposal[] filterProposals(
|
||||
ICCompletionProposal[] proposals) {
|
||||
return proposals ;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
<extension-point id="textHovers" name="%textHoversName"/>
|
||||
<extension-point id="IndexerPage" name="Indexer Page" schema="schema/IndexerPage.exsd"/>
|
||||
<extension-point id="completionContributors" name="%completionContributors" schema="schema/completionContributors.exsd"/>
|
||||
<extension-point id="ProposalFilter" name="Code Completion Proposal Filter" schema="schema/ProposalFilter.exsd"/>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.core.runtime.adapters">
|
||||
|
|
122
core/org.eclipse.cdt.ui/schema/ProposalFilter.exsd
Normal file
122
core/org.eclipse.cdt.ui/schema/ProposalFilter.exsd
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Schema file written by PDE -->
|
||||
<schema targetNamespace="org.eclipse.cdt.ui">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="org.eclipse.cdt.ui" id="CodeCompletionFilter" name="Code Completion Filter"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
This extension point allows contributors to make their implementation of ICompletionFilter known to the platform.
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref="ProposalFilter"/>
|
||||
</sequence>
|
||||
<attribute name="point" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute translatable="true"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="ProposalFilter">
|
||||
<complexType>
|
||||
<attribute name="id" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute translatable="true"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="class" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute kind="java"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="since"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
CDT 3.1
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="examples"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter extension point usage example here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="apiInfo"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter API information here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="implementation"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter information about supplied implementation of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="copyright"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
</schema>
|
|
@ -33,6 +33,7 @@ import org.eclipse.swt.graphics.RGB;
|
|||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
|
@ -63,6 +64,16 @@ public abstract class AbstractPreferencePage extends PreferencePage implements I
|
|||
fOverlayStore.setValue((String) fTextFields.get(text), text.getText());
|
||||
}
|
||||
};
|
||||
|
||||
protected Map fComboBoxes = new HashMap();
|
||||
private ModifyListener fComboBoxListener = new ModifyListener() {
|
||||
public void modifyText(ModifyEvent e) {
|
||||
Combo combo = (Combo) e.widget;
|
||||
String state = ProposalFilterPreferencesUtil.comboStateAsString(combo);
|
||||
fOverlayStore.setValue((String) fComboBoxes.get(combo), state);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected Map fCheckBoxes = new HashMap();
|
||||
private SelectionListener fCheckBoxListener = new SelectionListener() {
|
||||
|
@ -157,6 +168,24 @@ public abstract class AbstractPreferencePage extends PreferencePage implements I
|
|||
return textControl;
|
||||
}
|
||||
|
||||
protected void addComboBox(Composite composite, String label, String key, int textLimit, int indentation) {
|
||||
|
||||
Label labelControl = new Label(composite, SWT.NONE);
|
||||
labelControl.setText(label);
|
||||
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
|
||||
gd.horizontalIndent = indentation;
|
||||
labelControl.setLayoutData(gd);
|
||||
|
||||
Combo comboControl = new Combo(composite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); // TODO: When will the combo be disposed?
|
||||
gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
|
||||
gd.widthHint = convertWidthInCharsToPixels(textLimit + 1);
|
||||
comboControl.setLayoutData(gd);
|
||||
comboControl.setTextLimit(textLimit);
|
||||
fComboBoxes.put(comboControl, key);
|
||||
comboControl.addModifyListener(fComboBoxListener); // TODO: When will the listener be removed?
|
||||
|
||||
}
|
||||
|
||||
protected void addFiller(Composite composite) {
|
||||
PixelConverter pixelConverter= new PixelConverter(composite);
|
||||
Label filler= new Label(composite, SWT.LEFT );
|
||||
|
@ -292,11 +321,22 @@ public abstract class AbstractPreferencePage extends PreferencePage implements I
|
|||
String key = (String) fTextFields.get(t);
|
||||
t.setText(fOverlayStore.getString(key));
|
||||
}
|
||||
|
||||
e = fComboBoxes.keySet().iterator();
|
||||
while (e.hasNext()) {
|
||||
Combo c = (Combo) e.next();
|
||||
String key = (String) fComboBoxes.get(c);
|
||||
String state = fOverlayStore.getString(key);
|
||||
// Interpret the state string as a Combo state description
|
||||
ProposalFilterPreferencesUtil.restoreComboFromString(c, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
|
||||
*/
|
||||
public void init(IWorkbench workbench) {
|
||||
|
|
|
@ -58,6 +58,7 @@ public class CodeAssistPreferencePage extends AbstractPreferencePage {
|
|||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ContentAssistPreference.ADD_INCLUDE));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ContentAssistPreference.CURRENT_FILE_SEARCH_SCOPE));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ContentAssistPreference.PROJECT_SEARCH_SCOPE));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ContentAssistPreference.PROPOSALS_FILTER));
|
||||
|
||||
OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
|
||||
overlayKeys.toArray(keys);
|
||||
|
@ -135,7 +136,10 @@ public class CodeAssistPreferencePage extends AbstractPreferencePage {
|
|||
// label= PreferencesMessages.getString("CEditorPreferencePage.ContentAssistPage.parameterForegroundColor");
|
||||
// addColorButton(contentAssistComposite, label, ContentAssistPreference.PARAMETERS_FOREGROUND, 0);
|
||||
|
||||
initializeFields();
|
||||
label = PreferencesMessages.getString("CEditorPreferencePage.ContentAssistPage.proposalFilterSelect") ; //$NON-NLS-1$
|
||||
addComboBox(contentAssistComposite, label, ContentAssistPreference.PROPOSALS_FILTER, 20, 0);
|
||||
|
||||
initializeFields();
|
||||
|
||||
PlatformUI.getWorkbench().getHelpSystem().setHelp(contentAssistComposite, ICHelpContextIds.C_EDITOR_CONTENT_ASSIST_PREF_PAGE);
|
||||
|
||||
|
@ -168,6 +172,8 @@ public class CodeAssistPreferencePage extends AbstractPreferencePage {
|
|||
PreferenceConverter.setDefault(store, ContentAssistPreference.PARAMETERS_FOREGROUND, new RGB(0, 0, 0));
|
||||
store.setDefault(ContentAssistPreference.ORDER_PROPOSALS, false);
|
||||
store.setDefault(ContentAssistPreference.ADD_INCLUDE, true);
|
||||
store.setDefault(ContentAssistPreference.PROPOSALS_FILTER, ProposalFilterPreferencesUtil.getProposalFilternamesAsString()); // $NON_NLS 1$
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ CEditorPreferencePage.ContentAssistPage.autoActivationGroupTitle=Auto activation
|
|||
CEditorPreferencePage.ContentAssistPage.autoActivationEnableDot=Enable "." as trigger
|
||||
CEditorPreferencePage.ContentAssistPage.autoActivationEnableArrow=Enable "->" as trigger
|
||||
CEditorPreferencePage.ContentAssistPage.autoActivationDelay=dela&y (ms)
|
||||
CEditorPreferencePage.ContentAssistPage.proposalFilterSelect=Completion Proposal Filter:
|
||||
CEditorPreferencePage.ContentAssistPage.completionProposalBackgroundColor=&Background for completion proposals:
|
||||
CEditorPreferencePage.ContentAssistPage.completionProposalForegroundColor=&Foreground for completion proposals:
|
||||
CEditorPreferencePage.ContentAssistPage.parameterBackgroundColor=Bac&kground for method parameters:
|
||||
|
@ -260,3 +261,4 @@ PathEntryVariableSelectionDialog.ExtensionDialog.description = Choose extension
|
|||
|
||||
#Indexer
|
||||
IndexerPrefs.description=Sets default Indexer Options for new Projects
|
||||
ProposalFilterPreferencesUtil.defaultFilterName=<Default Filter>
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
package org.eclipse.cdt.internal.ui.preferences;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.InvalidRegistryObjectException;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
|
||||
/**
|
||||
* A class which encapsulates several utility functions
|
||||
* related to code completion preference settings.
|
||||
*/
|
||||
public class ProposalFilterPreferencesUtil {
|
||||
|
||||
/**
|
||||
* Private default constructor prevents instantiation
|
||||
*/
|
||||
private ProposalFilterPreferencesUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of proposal filter names
|
||||
* (i.e. the human-readable text for display
|
||||
* to fill into the Combo)
|
||||
*/
|
||||
public static String[] getProposalFilterNames() {
|
||||
ArrayList names = new ArrayList();
|
||||
try {
|
||||
IExtensionPoint point = Platform.getExtensionRegistry()
|
||||
.getExtensionPoint(CUIPlugin.PLUGIN_ID, "ProposalFilter"); //$NON-NLS-1$
|
||||
if (point != null) {
|
||||
IExtension[] extensions = point.getExtensions();
|
||||
for (int i = 0; i < extensions.length; i++) {
|
||||
IExtension extension = extensions[i];
|
||||
IConfigurationElement[] elements = extension
|
||||
.getConfigurationElements();
|
||||
for (int j = 0; j < elements.length; ++j) {
|
||||
IConfigurationElement element = elements[j];
|
||||
if ("ProposalFilter".equals(element.getName())) { //$NON-NLS-1$
|
||||
String filterName = element.getAttribute("name");
|
||||
if (null != filterName) {
|
||||
names.add(filterName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InvalidRegistryObjectException e) {
|
||||
// No action required since we will at least be using the fail-safe default filter
|
||||
CUIPlugin.getDefault().log(e);
|
||||
}
|
||||
String[] filterNames = (String[]) names
|
||||
.toArray(new String[names.size()]);
|
||||
return filterNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up all contributed completion proposal filters
|
||||
* and return their names as a semicolon-separated list
|
||||
* plus a leading entry for the selected index 0,
|
||||
* plus a leading <default> entry. <br>
|
||||
* A Combo may be initialized from this string.
|
||||
* @return The list of filter names
|
||||
*/
|
||||
public static String getProposalFilternamesAsString() {
|
||||
StringBuffer filterNames = new StringBuffer("0;");
|
||||
filterNames.append("<Default Filter>"); // TODO: NP externalize this!
|
||||
String[] names = getProposalFilterNames();
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
String name = names[i];
|
||||
filterNames.append(";");
|
||||
filterNames.append(name);
|
||||
}
|
||||
return filterNames.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration element which corresponds
|
||||
* to the human-readable filter name
|
||||
* @param filterName The human-readable filter name
|
||||
* @return The configuration element, or null if there is none
|
||||
*/
|
||||
public static IConfigurationElement getElementForName(String filterName) {
|
||||
IConfigurationElement element = null;
|
||||
IExtensionPoint point = Platform.getExtensionRegistry()
|
||||
.getExtensionPoint(CUIPlugin.PLUGIN_ID, "ProposalFilter"); //$NON-NLS-1$
|
||||
if (point != null) {
|
||||
try {
|
||||
IExtension[] extensions = point.getExtensions();
|
||||
if (extensions.length >= 1) {
|
||||
for (int i = 0; i < extensions.length; i++) {
|
||||
IExtension extension = extensions[i];
|
||||
|
||||
IConfigurationElement[] elements = extension
|
||||
.getConfigurationElements();
|
||||
|
||||
for (int j = 0; j < elements.length; ++j) {
|
||||
IConfigurationElement testElement = elements[j];
|
||||
if ("ProposalFilter".equals(testElement.getName())) { //$NON-NLS-1$
|
||||
String testName = testElement
|
||||
.getAttribute("name");
|
||||
if ((null != testName)
|
||||
&& (filterName.equals(testName))) {
|
||||
element = testElement;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Did we find the corresponding element?
|
||||
if (null != element)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (InvalidRegistryObjectException e) {
|
||||
// In case of failure we'll just return null
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of a Combo consists of the list of entries
|
||||
* and the index of the selected entry.
|
||||
* This method converts the state of the given Combo
|
||||
* to a string representation for storage in a preference store. <br>
|
||||
* The string contains a semicolon-separated list of entries.
|
||||
* The first entry is the index of the selected entry.
|
||||
* The following entries are the texts of the individual fields. <br>
|
||||
* Since the semicolon is the separator, the entries cannot contain semicolons.
|
||||
* This method will replace semicolons with commas if any are found.
|
||||
* @param combo The Combo whose state shall be converted
|
||||
* @return A string representation of the Combo state
|
||||
*/
|
||||
public static String comboStateAsString(Combo combo) {
|
||||
StringBuffer text = new StringBuffer();
|
||||
int selectionIndex = combo.getSelectionIndex();
|
||||
text.append(selectionIndex);
|
||||
String[] entries = combo.getItems();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
text.append(";");
|
||||
String entry = entries[i].replaceAll(";", ",");
|
||||
text.append(entry);
|
||||
}
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of a Combo consists of the list of entries
|
||||
* and the index of the selected entry.
|
||||
* This method takes a string representation of the state (e.g. from a preference store)
|
||||
* and restores it into the Combo. <br>
|
||||
* For a description of the text format see method comboStateAsString().
|
||||
* @param combo The combo to be restored.
|
||||
* @param text The text representation of the state.
|
||||
*/
|
||||
public static void restoreComboFromString(Combo combo, String text) {
|
||||
try {
|
||||
int endFirstEntry = text.indexOf(";");
|
||||
if (endFirstEntry > 0) { // First entry must contain at least one character
|
||||
String selectedString = text.substring(0, endFirstEntry);
|
||||
int selectedIndex = Integer.parseInt(selectedString);
|
||||
String[] entryList = text.substring(endFirstEntry + 1,
|
||||
text.length()).split(";");
|
||||
combo.setItems(entryList);
|
||||
combo.select(selectedIndex);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// If this fails we just return the unmodified Combo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience class wraps the data to initialize a Combo
|
||||
*/
|
||||
public static class ComboState {
|
||||
public int selectedIndex;
|
||||
|
||||
public String[] items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to extract the state of a Combo
|
||||
* from the state string stored e.g. in a preference store
|
||||
* @param comboPreference The state string
|
||||
* @return A ComboState instance.
|
||||
*/
|
||||
public static ComboState getComboState(String comboPreference) {
|
||||
ComboState state = new ComboState();
|
||||
try {
|
||||
int endFirstEntry = comboPreference.indexOf(";");
|
||||
if (endFirstEntry > 0) { // First entry must contain at least one character
|
||||
String selectedString = comboPreference.substring(0,
|
||||
endFirstEntry);
|
||||
state.selectedIndex = Integer.parseInt(selectedString);
|
||||
state.items = comboPreference.substring(endFirstEntry + 1,
|
||||
comboPreference.length()).split(";");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// If this fails we return an empty ComboState
|
||||
state.items = new String[0];
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the setting for the preferred proposal filter
|
||||
* and return it's configuration element.
|
||||
* @return The configuration element, or null if none is found.
|
||||
*/
|
||||
public static IConfigurationElement getPreferredFilterElement() {
|
||||
IConfigurationElement preferredElement = null;
|
||||
try {
|
||||
IPreferenceStore store = CUIPlugin.getDefault()
|
||||
.getPreferenceStore();
|
||||
String filterComboStateString = store
|
||||
.getString(ContentAssistPreference.PROPOSALS_FILTER);
|
||||
ComboState state = getComboState(filterComboStateString);
|
||||
preferredElement = getElementForName(state.items[state.selectedIndex]);
|
||||
} catch (Exception e) {
|
||||
// If anything goes wrong we'll just return null
|
||||
}
|
||||
return preferredElement;
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.CDOM;
|
||||
|
@ -22,17 +21,21 @@ import org.eclipse.cdt.core.dom.IASTServiceProvider.UnsupportedDialectException;
|
|||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.internal.ui.CUIMessages;
|
||||
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
|
||||
import org.eclipse.cdt.internal.ui.text.CParameterListValidator;
|
||||
import org.eclipse.cdt.internal.ui.util.ExternalEditorInput;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
||||
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IStorage;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.InvalidRegistryObjectException;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
|
@ -128,48 +131,12 @@ public class CCompletionProcessor2 implements IContentAssistProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
ICCompletionProposal[] propsArray = null;
|
||||
IProposalFilter filter = getCompletionFilter();
|
||||
ICCompletionProposal[] proposalsInput = (ICCompletionProposal[]) proposals.toArray(new ICCompletionProposal[proposals.size()]) ;
|
||||
|
||||
if (!proposals.isEmpty()) {
|
||||
errorMessage = null;
|
||||
propsArray = (ICCompletionProposal[])proposals.toArray(new ICCompletionProposal[proposals.size()]);
|
||||
CCompletionProposalComparator propsComp = new CCompletionProposalComparator();
|
||||
propsComp.setOrderAlphabetically(true);
|
||||
Arrays.sort(propsArray, propsComp);
|
||||
|
||||
// remove duplicates but leave the ones with return types
|
||||
|
||||
int last = 0;
|
||||
int removed = 0;
|
||||
for (int i = 1; i < propsArray.length; ++i) {
|
||||
if (propsComp.compare(propsArray[last], propsArray[i]) == 0) {
|
||||
// We want to leave the one that has the return string if any
|
||||
boolean lastReturn = propsArray[last].getIdString() != propsArray[last].getDisplayString();
|
||||
boolean iReturn = propsArray[i].getIdString() != propsArray[i].getDisplayString();
|
||||
|
||||
if (!lastReturn && iReturn)
|
||||
// flip i down to last
|
||||
propsArray[last] = propsArray[i];
|
||||
|
||||
// Remove the duplicate
|
||||
propsArray[i] = null;
|
||||
++removed;
|
||||
} else
|
||||
// update last
|
||||
last = i;
|
||||
}
|
||||
if (removed > 0) {
|
||||
// Strip out the null entries
|
||||
ICCompletionProposal[] newArray = new ICCompletionProposal[propsArray.length - removed];
|
||||
int j = 0;
|
||||
for (int i = 0; i < propsArray.length; ++i)
|
||||
if (propsArray[i] != null)
|
||||
newArray[j++] = propsArray[i];
|
||||
propsArray = newArray;
|
||||
}
|
||||
}
|
||||
ICCompletionProposal[] proposalsFiltered = filter.filterProposals(proposalsInput);
|
||||
|
||||
return propsArray;
|
||||
return proposalsFiltered;
|
||||
|
||||
} catch (UnsupportedDialectException e) {
|
||||
errorMessage = CUIMessages.getString(dialectError);
|
||||
|
@ -179,6 +146,32 @@ public class CCompletionProcessor2 implements IContentAssistProcessor {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IProposalFilter getCompletionFilter() {
|
||||
IProposalFilter filter = null;
|
||||
try {
|
||||
IConfigurationElement filterElement = ProposalFilterPreferencesUtil.getPreferredFilterElement();
|
||||
if (null != filterElement) {
|
||||
Object contribObject = filterElement
|
||||
.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
if ((contribObject instanceof IProposalFilter)) {
|
||||
filter = (IProposalFilter) contribObject;
|
||||
}
|
||||
}
|
||||
} catch (InvalidRegistryObjectException e) {
|
||||
// No action required since we will be using the fail-safe default filter
|
||||
CUIPlugin.getDefault().log(e);
|
||||
} catch (CoreException e) {
|
||||
// No action required since we will be using the fail-safe default filter
|
||||
CUIPlugin.getDefault().log(e);
|
||||
}
|
||||
|
||||
if (null == filter) {
|
||||
// fail-safe default implementation
|
||||
filter = new DefaultProposalFilter();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
private String scanPrefix(IDocument document, int end) {
|
||||
try {
|
||||
|
|
|
@ -63,7 +63,9 @@ public class ContentAssistPreference {
|
|||
public final static String CURRENT_FILE_SEARCH_SCOPE= "content_assist_current_file_search_scope"; //$NON-NLS-1$
|
||||
/** Preference key for completion search scope */
|
||||
public final static String PROJECT_SEARCH_SCOPE= "content_assist_project_search_scope"; //$NON-NLS-1$
|
||||
|
||||
/** Preference key for completion filtering */
|
||||
public final static String PROPOSALS_FILTER= "content_assist_proposal_filter"; //$NON_NLS 1$
|
||||
|
||||
private static Color getColor(IPreferenceStore store, String key, IColorManager manager) {
|
||||
RGB rgb= PreferenceConverter.getColor(store, key);
|
||||
return manager.getColor(rgb);
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
|
||||
|
||||
/**
|
||||
* The default code completion filter: Remove duplicate entries on the basis of
|
||||
* their id string. Use CCompletionProposalComparator for sorting.
|
||||
*/
|
||||
public class DefaultProposalFilter implements IProposalFilter {
|
||||
|
||||
public ICCompletionProposal[] filterProposals(
|
||||
ICCompletionProposal[] proposals) {
|
||||
|
||||
CCompletionProposalComparator propsComp = new CCompletionProposalComparator();
|
||||
propsComp.setOrderAlphabetically(true);
|
||||
Arrays.sort(proposals, propsComp);
|
||||
|
||||
// remove duplicates but leave the ones with return types
|
||||
|
||||
int last = 0;
|
||||
int removed = 0;
|
||||
for (int i = 1; i < proposals.length; ++i) {
|
||||
if (propsComp.compare(proposals[last], proposals[i]) == 0) {
|
||||
// We want to leave the one that has the return string if any
|
||||
boolean lastReturn = proposals[last].getIdString() != proposals[last]
|
||||
.getDisplayString();
|
||||
boolean iReturn = proposals[i].getIdString() != proposals[i]
|
||||
.getDisplayString();
|
||||
|
||||
if (!lastReturn && iReturn)
|
||||
// flip i down to last
|
||||
proposals[last] = proposals[i];
|
||||
|
||||
// Remove the duplicate
|
||||
proposals[i] = null;
|
||||
++removed;
|
||||
} else
|
||||
// update last
|
||||
last = i;
|
||||
}
|
||||
if (removed > 0) {
|
||||
// Strip out the null entries
|
||||
ICCompletionProposal[] newArray = new ICCompletionProposal[proposals.length
|
||||
- removed];
|
||||
int j = 0;
|
||||
for (int i = 0; i < proposals.length; ++i)
|
||||
if (proposals[i] != null)
|
||||
newArray[j++] = proposals[i];
|
||||
proposals = newArray;
|
||||
}
|
||||
|
||||
return proposals;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.eclipse.cdt.ui.text.contentassist;
|
||||
|
||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||
|
||||
|
||||
public interface IProposalFilter {
|
||||
|
||||
/**
|
||||
* Filter a list of ICCompletionProposals <br>
|
||||
* - Change the order of entries <br>
|
||||
* - Remove undesired (duplicate) entries <br>
|
||||
* - Supplement existing entries with additional information
|
||||
* @param proposals The List of proposals
|
||||
* @return The filtered list of proposals as array
|
||||
*/
|
||||
ICCompletionProposal[] filterProposals(ICCompletionProposal[] proposals) ;
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue