From 673ff7a988f1b4747c539b1d68cf5b8364e6561c Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Tue, 5 Jul 2005 20:32:07 +0000 Subject: [PATCH] Bug 98881. Improving support for search in completion. --- .../contentassist/CCompletionProcessor2.java | 67 +++++++++--- .../DOMCompletionContributor.java | 2 +- .../HelpCompletionContributor.java | 4 +- .../SearchCompletionContributor.java | 103 ++++++++++-------- .../ui/text/template/TemplateEngine.java | 1 + .../contentassist/ICompletionContributor.java | 1 + 6 files changed, 110 insertions(+), 68 deletions(-) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java index beb9c2eb631..4de0ee555e6 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java @@ -30,6 +30,9 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; 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.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; @@ -58,27 +61,40 @@ public class CCompletionProcessor2 implements IContentAssistProcessor { /* (non-Javadoc) * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int) */ - public ICompletionProposal[] computeCompletionProposals(final ITextViewer viewer, - int offset) { + public ICompletionProposal[] computeCompletionProposals(final ITextViewer viewer, int offset) { try { IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput()); ASTCompletionNode completionNode = null; - 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)); - } + String prefix = null; + + IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore(); + boolean fileScope = store.getBoolean(ContentAssistPreference.CURRENT_FILE_SEARCH_SCOPE); + boolean projectScope = store.getBoolean(ContentAssistPreference.PROJECT_SEARCH_SCOPE); + 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); List proposals = new ArrayList(); @@ -97,7 +113,7 @@ public class CCompletionProcessor2 implements IContentAssistProcessor { if (!(contribObject instanceof ICompletionContributor)) continue; 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; } + 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) * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int) */ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionContributor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionContributor.java index 6dbe70f97ac..00cde4cc4fd 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionContributor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionContributor.java @@ -51,6 +51,7 @@ public class DOMCompletionContributor implements ICompletionContributor { int offset, IWorkingCopy workingCopy, ASTCompletionNode completionNode, + String prefix, List proposals) { if (completionNode != null) { IASTName[] names = completionNode.getNames(); @@ -82,7 +83,6 @@ public class DOMCompletionContributor implements ICompletionContributor { } // Find all macros if there is a prefix - String prefix = completionNode.getPrefix(); if (prefix.length() > 0) { IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions(); if (macros != null) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/HelpCompletionContributor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/HelpCompletionContributor.java index ae11492e08d..1657766e4de 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/HelpCompletionContributor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/HelpCompletionContributor.java @@ -31,7 +31,7 @@ import org.eclipse.swt.graphics.Image; public class HelpCompletionContributor implements ICompletionContributor { public void contributeCompletionProposals(ITextViewer viewer, int offset, - IWorkingCopy workingCopy, ASTCompletionNode completionNode, + IWorkingCopy workingCopy, ASTCompletionNode completionNode, String prefix, List proposals) { final IWorkingCopy fWorkingCopy = workingCopy; @@ -60,8 +60,6 @@ public class HelpCompletionContributor implements ICompletionContributor { if (name.getParent() instanceof IASTFieldReference) continue; - String prefix = new String(name.toCharArray()); - IFunctionSummary[] summaries = CHelpProviderManager.getDefault().getMatchingFunctions(context, prefix); if (summaries == null ) continue; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/SearchCompletionContributor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/SearchCompletionContributor.java index a85a835c676..8eeceb7ae6d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/SearchCompletionContributor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/SearchCompletionContributor.java @@ -34,59 +34,70 @@ import org.eclipse.swt.graphics.Image; public class SearchCompletionContributor implements ICompletionContributor { public void contributeCompletionProposals(ITextViewer viewer, int offset, - IWorkingCopy workingCopy, ASTCompletionNode completionNode, + IWorkingCopy workingCopy, ASTCompletionNode completionNode, String prefix, List proposals) { - // and only for C source files - if (workingCopy.isHeaderUnit() || !workingCopy.isCLanguage()) { - return; - } - if (completionNode != null) { - IASTName[] names = completionNode.getNames(); - for (int i = 0; i < names.length; i++) { - IASTName name = names[i]; + if (!validContext(completionNode)) + return; + + // Create search engine + SearchEngine searchEngine = new SearchEngine(); + searchEngine.setWaitingPolicy( ICSearchConstants.FORCE_IMMEDIATE_SEARCH ); - // not hooked up, ignore - if (name.getTranslationUnit() == null) - continue; + // Create search scope + ICElement[] projects = new ICElement[] { workingCopy.getCProject() }; + //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 - if (name.getParent() instanceof IASTFieldReference) - continue; - - // Create search engine - SearchEngine searchEngine = new SearchEngine(); - searchEngine.setWaitingPolicy( ICSearchConstants.FORCE_IMMEDIATE_SEARCH ); - - // Create search scope - ICElement[] projects = new ICElement[] { workingCopy.getCProject() }; - ICSearchScope scope = SearchEngine.createCSearchScope(projects, true); - - // Create the pattern - 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); - } - } + // 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, prefix, offset, proposals); } - // TODO else search the prefix text } - private void handleFunction(String name, ITextViewer viewer, ASTCompletionNode completionNode, int offset, List proposals) { - int repLength = completionNode.getLength(); + private boolean validContext(ASTCompletionNode completionNode) { + 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; Image image = CUIPlugin.getImageDescriptorRegistry().get(CElementImageProvider.getFunctionImageDescriptor()); String repString = name + "()"; //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/template/TemplateEngine.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/template/TemplateEngine.java index 4fcc066be1b..716094f70df 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/template/TemplateEngine.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/template/TemplateEngine.java @@ -151,6 +151,7 @@ public class TemplateEngine implements ICompletionContributor { int offset, IWorkingCopy workingCopy, ASTCompletionNode completionNode, + String prefix, List proposals) { // TODO We should use the completion node to determine the proper context for the templates diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/contentassist/ICompletionContributor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/contentassist/ICompletionContributor.java index bdaa83e28d9..da63304ceea 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/contentassist/ICompletionContributor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/contentassist/ICompletionContributor.java @@ -31,6 +31,7 @@ public interface ICompletionContributor { int offset, IWorkingCopy workingCopy, ASTCompletionNode completionNode, + String prefix, List proposals); }