mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 98881. Improving support for search in completion.
This commit is contained in:
parent
6833f73fa5
commit
673ff7a988
6 changed files with 110 additions and 68 deletions
|
@ -30,6 +30,9 @@ import org.eclipse.core.runtime.IConfigurationElement;
|
||||||
import org.eclipse.core.runtime.IExtension;
|
import org.eclipse.core.runtime.IExtension;
|
||||||
import org.eclipse.core.runtime.IExtensionPoint;
|
import org.eclipse.core.runtime.IExtensionPoint;
|
||||||
import org.eclipse.core.runtime.Platform;
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||||
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
|
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
|
||||||
|
@ -58,27 +61,40 @@ public class CCompletionProcessor2 implements IContentAssistProcessor {
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
|
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
|
||||||
*/
|
*/
|
||||||
public ICompletionProposal[] computeCompletionProposals(final ITextViewer viewer,
|
public ICompletionProposal[] computeCompletionProposals(final ITextViewer viewer, int offset) {
|
||||||
int offset) {
|
|
||||||
try {
|
try {
|
||||||
IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
|
IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
|
||||||
ASTCompletionNode completionNode = null;
|
ASTCompletionNode completionNode = null;
|
||||||
IFile file = (IFile)workingCopy.getResource();
|
String prefix = null;
|
||||||
if (file != null)
|
|
||||||
completionNode = CDOM.getInstance().getCompletionNode(
|
IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore();
|
||||||
file,
|
boolean fileScope = store.getBoolean(ContentAssistPreference.CURRENT_FILE_SEARCH_SCOPE);
|
||||||
offset,
|
boolean projectScope = store.getBoolean(ContentAssistPreference.PROJECT_SEARCH_SCOPE);
|
||||||
CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_WORKING_COPY_WHENEVER_POSSIBLE));
|
|
||||||
else if (editor.getEditorInput() instanceof ExternalEditorInput) {
|
|
||||||
IStorage storage = ((ExternalEditorInput)(editor.getEditorInput())).getStorage();
|
|
||||||
IProject project = workingCopy.getCProject().getProject();
|
|
||||||
completionNode = CDOM.getInstance().getCompletionNode(
|
|
||||||
storage,
|
|
||||||
project,
|
|
||||||
offset,
|
|
||||||
CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_WORKING_COPY_WHENEVER_POSSIBLE));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (fileScope) { // do a full parse
|
||||||
|
IFile file = (IFile)workingCopy.getResource();
|
||||||
|
if (file != null)
|
||||||
|
completionNode = CDOM.getInstance().getCompletionNode(
|
||||||
|
file,
|
||||||
|
offset,
|
||||||
|
CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_WORKING_COPY_WHENEVER_POSSIBLE));
|
||||||
|
else if (editor.getEditorInput() instanceof ExternalEditorInput) {
|
||||||
|
IStorage storage = ((ExternalEditorInput)(editor.getEditorInput())).getStorage();
|
||||||
|
IProject project = workingCopy.getCProject().getProject();
|
||||||
|
completionNode = CDOM.getInstance().getCompletionNode(
|
||||||
|
storage,
|
||||||
|
project,
|
||||||
|
offset,
|
||||||
|
CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_WORKING_COPY_WHENEVER_POSSIBLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completionNode != null)
|
||||||
|
prefix = completionNode.getPrefix();
|
||||||
|
|
||||||
|
} else if (projectScope) { // find the prefix from the document
|
||||||
|
prefix = scanPrefix(viewer.getDocument(), offset);
|
||||||
|
}
|
||||||
|
|
||||||
errorMessage = CUIMessages.getString(noCompletions);
|
errorMessage = CUIMessages.getString(noCompletions);
|
||||||
|
|
||||||
List proposals = new ArrayList();
|
List proposals = new ArrayList();
|
||||||
|
@ -97,7 +113,7 @@ public class CCompletionProcessor2 implements IContentAssistProcessor {
|
||||||
if (!(contribObject instanceof ICompletionContributor))
|
if (!(contribObject instanceof ICompletionContributor))
|
||||||
continue;
|
continue;
|
||||||
ICompletionContributor contributor = (ICompletionContributor)contribObject;
|
ICompletionContributor contributor = (ICompletionContributor)contribObject;
|
||||||
contributor.contributeCompletionProposals(viewer, offset, workingCopy, completionNode, proposals);
|
contributor.contributeCompletionProposals(viewer, offset, workingCopy, completionNode, prefix, proposals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +160,21 @@ public class CCompletionProcessor2 implements IContentAssistProcessor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String scanPrefix(IDocument document, int end) {
|
||||||
|
try {
|
||||||
|
int start = end;
|
||||||
|
while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
|
||||||
|
start--;
|
||||||
|
|
||||||
|
if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1)))
|
||||||
|
start--;
|
||||||
|
|
||||||
|
return document.get(start, end - start);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
|
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
int offset,
|
int offset,
|
||||||
IWorkingCopy workingCopy,
|
IWorkingCopy workingCopy,
|
||||||
ASTCompletionNode completionNode,
|
ASTCompletionNode completionNode,
|
||||||
|
String prefix,
|
||||||
List proposals) {
|
List proposals) {
|
||||||
if (completionNode != null) {
|
if (completionNode != null) {
|
||||||
IASTName[] names = completionNode.getNames();
|
IASTName[] names = completionNode.getNames();
|
||||||
|
@ -82,7 +83,6 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all macros if there is a prefix
|
// Find all macros if there is a prefix
|
||||||
String prefix = completionNode.getPrefix();
|
|
||||||
if (prefix.length() > 0) {
|
if (prefix.length() > 0) {
|
||||||
IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions();
|
IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions();
|
||||||
if (macros != null)
|
if (macros != null)
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.eclipse.swt.graphics.Image;
|
||||||
public class HelpCompletionContributor implements ICompletionContributor {
|
public class HelpCompletionContributor implements ICompletionContributor {
|
||||||
|
|
||||||
public void contributeCompletionProposals(ITextViewer viewer, int offset,
|
public void contributeCompletionProposals(ITextViewer viewer, int offset,
|
||||||
IWorkingCopy workingCopy, ASTCompletionNode completionNode,
|
IWorkingCopy workingCopy, ASTCompletionNode completionNode, String prefix,
|
||||||
List proposals)
|
List proposals)
|
||||||
{
|
{
|
||||||
final IWorkingCopy fWorkingCopy = workingCopy;
|
final IWorkingCopy fWorkingCopy = workingCopy;
|
||||||
|
@ -60,8 +60,6 @@ public class HelpCompletionContributor implements ICompletionContributor {
|
||||||
if (name.getParent() instanceof IASTFieldReference)
|
if (name.getParent() instanceof IASTFieldReference)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
String prefix = new String(name.toCharArray());
|
|
||||||
|
|
||||||
IFunctionSummary[] summaries = CHelpProviderManager.getDefault().getMatchingFunctions(context, prefix);
|
IFunctionSummary[] summaries = CHelpProviderManager.getDefault().getMatchingFunctions(context, prefix);
|
||||||
if (summaries == null )
|
if (summaries == null )
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -34,59 +34,70 @@ import org.eclipse.swt.graphics.Image;
|
||||||
public class SearchCompletionContributor implements ICompletionContributor {
|
public class SearchCompletionContributor implements ICompletionContributor {
|
||||||
|
|
||||||
public void contributeCompletionProposals(ITextViewer viewer, int offset,
|
public void contributeCompletionProposals(ITextViewer viewer, int offset,
|
||||||
IWorkingCopy workingCopy, ASTCompletionNode completionNode,
|
IWorkingCopy workingCopy, ASTCompletionNode completionNode, String prefix,
|
||||||
List proposals)
|
List proposals)
|
||||||
{
|
{
|
||||||
// and only for C source files
|
if (!validContext(completionNode))
|
||||||
if (workingCopy.isHeaderUnit() || !workingCopy.isCLanguage()) {
|
return;
|
||||||
return;
|
|
||||||
}
|
// Create search engine
|
||||||
if (completionNode != null) {
|
SearchEngine searchEngine = new SearchEngine();
|
||||||
IASTName[] names = completionNode.getNames();
|
searchEngine.setWaitingPolicy( ICSearchConstants.FORCE_IMMEDIATE_SEARCH );
|
||||||
for (int i = 0; i < names.length; i++) {
|
|
||||||
IASTName name = names[i];
|
|
||||||
|
|
||||||
// not hooked up, ignore
|
// Create search scope
|
||||||
if (name.getTranslationUnit() == null)
|
ICElement[] projects = new ICElement[] { workingCopy.getCProject() };
|
||||||
continue;
|
//ICSearchScope scope = SearchEngine.createCSearchScope(projects, true);
|
||||||
|
ICSearchScope scope = SearchEngine.createWorkspaceScope();
|
||||||
|
|
||||||
|
// Create the pattern
|
||||||
|
ICSearchPattern pattern = SearchEngine.createSearchPattern(prefix + "*", ICSearchConstants.FUNCTION, ICSearchConstants.DECLARATIONS, false); //$NON-NLS-1$
|
||||||
|
|
||||||
// ignore if this is a member access
|
// Run the search
|
||||||
if (name.getParent() instanceof IASTFieldReference)
|
BasicSearchResultCollector collector = new BasicSearchResultCollector();
|
||||||
continue;
|
try {
|
||||||
|
searchEngine.search(CUIPlugin.getWorkspace(), pattern, scope, collector, false);
|
||||||
// Create search engine
|
} catch (InterruptedException e) {
|
||||||
SearchEngine searchEngine = new SearchEngine();
|
return;
|
||||||
searchEngine.setWaitingPolicy( ICSearchConstants.FORCE_IMMEDIATE_SEARCH );
|
}
|
||||||
|
|
||||||
// Create search scope
|
Set results = collector.getSearchResults();
|
||||||
ICElement[] projects = new ICElement[] { workingCopy.getCProject() };
|
Iterator iResults = results.iterator();
|
||||||
ICSearchScope scope = SearchEngine.createCSearchScope(projects, true);
|
while (iResults.hasNext()) {
|
||||||
|
BasicSearchMatch match = (BasicSearchMatch)iResults.next();
|
||||||
// Create the pattern
|
handleFunction(match.getName(), viewer, prefix, offset, proposals);
|
||||||
String prefix = new String(name.toCharArray()) + "*"; //$NON-NLS-1$
|
|
||||||
ICSearchPattern pattern = SearchEngine.createSearchPattern(prefix, ICSearchConstants.FUNCTION, ICSearchConstants.DEFINITIONS, false);
|
|
||||||
|
|
||||||
// Run the search
|
|
||||||
BasicSearchResultCollector collector = new BasicSearchResultCollector();
|
|
||||||
try {
|
|
||||||
searchEngine.search(CUIPlugin.getWorkspace(), pattern, scope, collector, false);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set results = collector.getSearchResults();
|
|
||||||
Iterator iResults = results.iterator();
|
|
||||||
while (iResults.hasNext()) {
|
|
||||||
BasicSearchMatch match = (BasicSearchMatch)iResults.next();
|
|
||||||
handleFunction(match.getName(), viewer, completionNode, offset, proposals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TODO else search the prefix text
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleFunction(String name, ITextViewer viewer, ASTCompletionNode completionNode, int offset, List proposals) {
|
private boolean validContext(ASTCompletionNode completionNode) {
|
||||||
int repLength = completionNode.getLength();
|
if (completionNode == null)
|
||||||
|
// No completion node, assume true
|
||||||
|
return true;
|
||||||
|
|
||||||
|
boolean valid = true;
|
||||||
|
IASTName[] names = completionNode.getNames();
|
||||||
|
for (int i = 0; i < names.length; i++) {
|
||||||
|
IASTName name = names[i];
|
||||||
|
|
||||||
|
// not hooked up, not a valid name, ignore
|
||||||
|
if (name.getTranslationUnit() == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// member access currently isn't valid
|
||||||
|
if (name.getParent() instanceof IASTFieldReference) {
|
||||||
|
valid = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// found one that was valid
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Couldn't find a valid context
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleFunction(String name, ITextViewer viewer, String prefix, int offset, List proposals) {
|
||||||
|
int repLength = prefix.length();
|
||||||
int repOffset = offset - repLength;
|
int repOffset = offset - repLength;
|
||||||
Image image = CUIPlugin.getImageDescriptorRegistry().get(CElementImageProvider.getFunctionImageDescriptor());
|
Image image = CUIPlugin.getImageDescriptorRegistry().get(CElementImageProvider.getFunctionImageDescriptor());
|
||||||
String repString = name + "()"; //$NON-NLS-1$
|
String repString = name + "()"; //$NON-NLS-1$
|
||||||
|
|
|
@ -151,6 +151,7 @@ public class TemplateEngine implements ICompletionContributor {
|
||||||
int offset,
|
int offset,
|
||||||
IWorkingCopy workingCopy,
|
IWorkingCopy workingCopy,
|
||||||
ASTCompletionNode completionNode,
|
ASTCompletionNode completionNode,
|
||||||
|
String prefix,
|
||||||
List proposals)
|
List proposals)
|
||||||
{
|
{
|
||||||
// TODO We should use the completion node to determine the proper context for the templates
|
// TODO We should use the completion node to determine the proper context for the templates
|
||||||
|
|
|
@ -31,6 +31,7 @@ public interface ICompletionContributor {
|
||||||
int offset,
|
int offset,
|
||||||
IWorkingCopy workingCopy,
|
IWorkingCopy workingCopy,
|
||||||
ASTCompletionNode completionNode,
|
ASTCompletionNode completionNode,
|
||||||
|
String prefix,
|
||||||
List proposals);
|
List proposals);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue