[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Big Huge CEditor Patch
|
Folks,
Here is a big patch (sorry, I tried to keep it small, but one thing just
kept leading to another) which represents a new baseline for the code
completion feature of the C/C++ Editor. It has cleaned up some (but not
all) of the Java'isms in this area and now allows for two features,
proposal help information and argument hovers, not previously available.
Next up will be the work to fill out the jump to definition, auto add
include support, sticky context menus and the like.
Thanks,
Thomas
CHANGELOG:
- Proposals will now include additional help information with them
if it is available (same as JDT). This opens the door for being
able to write a Javadoc/Doxygen parser and integrating live,
context specific, help.
- On function completions a hover is now shown above the function
(same as JDT) with the argument information as it is being filled
in.
Index: src/org/eclipse/cdt/internal/ui/cview/CView.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/CView.java,v
retrieving revision 1.25
diff -u -r1.25 CView.java
--- src/org/eclipse/cdt/internal/ui/cview/CView.java 27 May 2003 21:33:02 -0000 1.25
+++ src/org/eclipse/cdt/internal/ui/cview/CView.java 23 Jun 2003 19:18:40 -0000
@@ -43,9 +43,7 @@
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
-import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
-import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
@@ -94,6 +92,7 @@
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ResourceWorkingSetFilter;
import org.eclipse.ui.actions.AddBookmarkAction;
import org.eclipse.ui.actions.BuildAction;
import org.eclipse.ui.actions.CloseResourceAction;
@@ -108,6 +107,7 @@
import org.eclipse.ui.actions.OpenWithMenu;
import org.eclipse.ui.actions.RefreshAction;
import org.eclipse.ui.actions.RenameResourceAction;
+import org.eclipse.ui.actions.WorkingSetFilterActionGroup;
import org.eclipse.ui.dialogs.PropertyDialogAction;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.PluginTransfer;
@@ -154,8 +154,7 @@
ForwardAction forwardAction;
GoIntoAction goIntoAction;
UpAction upAction;
- NewWorkingSetFilterAction wsFilterAction;
- AdjustWorkingSetFilterAction wsClearFilterAction;
+ WorkingSetFilterActionGroup wsFilterActionGroup;
FrameList frameList;
CViewFrameSource frameSource;
@@ -166,7 +165,8 @@
CLibFilter clibFilter = new CLibFilter ();
ShowLibrariesAction clibFilterAction;
- CWorkingSetFilter workingSetFilter = new CWorkingSetFilter ();
+ ResourceWorkingSetFilter workingSetFilter = new ResourceWorkingSetFilter();
+
ActionContributionItem adjustWorkingSetContributions [] = new ActionContributionItem[5];
// Collapsing
@@ -201,40 +201,34 @@
};
private IPropertyChangeListener workingSetListener = new IPropertyChangeListener() {
+ private void doViewerUpdate() {
+ viewer.getControl().setRedraw(false);
+ viewer.refresh();
+ viewer.getControl().setRedraw(true);
+ }
+
public void propertyChange(PropertyChangeEvent ev) {
String prop = ev.getProperty();
if(prop == null) {
return;
}
- if(prop.equals(CWorkingSetFilter.WORKING_SET_ACTIVE_CHANGED)) {
- updateWorkingSetMenu();
- viewer.getControl().setRedraw(false);
- viewer.refresh();
- viewer.getControl().setRedraw(true);
- } else if(prop.equals(IWorkingSetManager.CHANGE_WORKING_SET_ADD)) {
- updateWorkingSetMenu();
- } else if(prop.equals(IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE)) {
- updateWorkingSetMenu();
+ if(prop.equals(WorkingSetFilterActionGroup.CHANGE_WORKING_SET)) {
+ workingSetFilter.setWorkingSet((IWorkingSet)ev.getNewValue());
+ doViewerUpdate();
} else if(prop.equals(IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE)){
- if(ev.getOldValue() instanceof IWorkingSet) {
- String name = ((IWorkingSet)(ev.getOldValue())).getName();
- String wsName = workingSetFilter.getWorkingSetName();
- if(wsName != null && name.equals(wsName)) {
- viewer.getControl().setRedraw(false);
- viewer.refresh();
- viewer.getControl().setRedraw(true);
+ if(ev.getOldValue() instanceof IWorkingSet && workingSetFilter.getWorkingSet() != null) {
+ if(workingSetFilter.getWorkingSet().equals(ev.getOldValue())) {
+ doViewerUpdate();
}
}
} else if(prop.equals(IWorkingSetManager.CHANGE_WORKING_SET_REMOVE)) {
- if(ev.getOldValue() instanceof IWorkingSet) {
- String name = ((IWorkingSet)(ev.getOldValue())).getName();
- String wsName = workingSetFilter.getWorkingSetName();
- if(wsName != null && name.equals(wsName)) {
- workingSetFilter.setWorkingSetName(null);
+ if(ev.getOldValue() instanceof IWorkingSet && workingSetFilter.getWorkingSet() != null) {
+ if(workingSetFilter.getWorkingSet().equals(ev.getOldValue())) {
+ workingSetFilter.setWorkingSet(null);
+ doViewerUpdate();
}
}
- updateWorkingSetMenu();
}
}
};
@@ -422,10 +416,6 @@
CUIPlugin.getDefault().getProblemMarkerManager().addListener(viewer);
CUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
- IWorkingSetManager wsmanager = getViewSite().getWorkbenchWindow().getWorkbench().getWorkingSetManager();
- workingSetFilter.setWorkingSetManager(wsmanager);
-
-
// FIXME: Add Drag and Drop support.
initFrameList();
initRefreshKey();
@@ -455,8 +445,8 @@
makeActions();
//Add the property changes after all of the UI work has been done.
+ IWorkingSetManager wsmanager = getViewSite().getWorkbenchWindow().getWorkbench().getWorkingSetManager();
wsmanager.addPropertyChangeListener(workingSetListener);
- workingSetFilter.addChangeListener(workingSetListener);
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
@@ -559,13 +549,13 @@
return patternFilter;
}
- /**
- * Returns the working set filter for this view.
- * @return the working set filter
- */
- CWorkingSetFilter getWorkingSetFilter() {
- return workingSetFilter;
- }
+// /**
+// * Returns the working set filter for this view.
+// * @return the working set filter
+// */
+// CWorkingSetFilter getWorkingSetFilter() {
+// return workingSetFilter;
+// }
TreeViewer getViewer () {
return viewer;
@@ -601,8 +591,7 @@
patternFilterAction = new FilterSelectionAction(shell, this, "Filters...");
clibFilterAction = new ShowLibrariesAction(shell, this, "Show Referenced Libs");
- wsFilterAction = new NewWorkingSetFilterAction(getViewSite().getShell(), this, "Select Working Set...");
- wsClearFilterAction = new AdjustWorkingSetFilterAction("Deselect Working Set", null, workingSetFilter);
+ wsFilterActionGroup = new WorkingSetFilterActionGroup(getViewSite().getShell(), workingSetListener);
goIntoAction = new GoIntoAction(frameList);
backAction = new BackAction(frameList);
@@ -1039,65 +1028,14 @@
toolBar.add(collapseAllAction);
actionBars.updateActionBars();
- IMenuManager menu = actionBars.getMenuManager();
- menu.add(wsFilterAction);
- menu.add(wsClearFilterAction);
+ wsFilterActionGroup.fillActionBars(actionBars);
- menu.add(new Separator());
- menu.add(new GroupMarker(WORKING_GROUP_MARKER));
- menu.add(new GroupMarker(WORKING_GROUP_MARKER_END));
- menu.add(new Separator());
-
- updateWorkingSetMenu();
+ IMenuManager menu = actionBars.getMenuManager();
//menu.add (clibFilterAction);
menu.add (patternFilterAction);
}
- void updateWorkingSetMenu() {
- IMenuManager menu = getViewSite().getActionBars().getMenuManager();
-
- //Remove the previous entries
- for(int i = 0; i < adjustWorkingSetContributions.length; i++) {
- if(adjustWorkingSetContributions[i] != null) {
- menu.remove(adjustWorkingSetContributions[i]);
- }
- }
-
- //Find out what we are currently using
- String currentWorkingSetName = workingSetFilter.getWorkingSetName();
-
- //If we have no working set, then we can't disable it
- if(wsClearFilterAction != null) {
- wsClearFilterAction.setEnabled((currentWorkingSetName != null));
- }
-
- IWorkingSetManager manager = getViewSite().getWorkbenchWindow().getWorkbench().getWorkingSetManager();
- IWorkingSet recentsets [] = manager.getWorkingSets();
- for(int i = 0; i < adjustWorkingSetContributions.length; i++) {
- if(i < recentsets.length) {
- Action action = new AdjustWorkingSetFilterAction(recentsets[i].getName(),
- recentsets[i].getName(),
- workingSetFilter);
- adjustWorkingSetContributions[i] = new ActionContributionItem(action);
- if(currentWorkingSetName != null &&
- currentWorkingSetName.equals(recentsets[i].getName())) {
- adjustWorkingSetContributions[i].getAction().setChecked(true);
- }
- } else {
- adjustWorkingSetContributions[i] = null;
- }
- }
-
- //Put the new entries in
- for(int i = 0; i < adjustWorkingSetContributions.length; i++) {
- if(adjustWorkingSetContributions[i] != null) {
- menu.appendToGroup(WORKING_GROUP_MARKER, adjustWorkingSetContributions[i]);
- }
- }
- }
-
-
/**
* Sets the decorator for the package explorer.
*
@@ -1200,18 +1138,19 @@
}
else
initFilterFromPreferences();
+ }
- //restore working set
+ void restoreState(IMemento memento) {
+ //Restore the working set before we re-build the tree
String wsname = memento.getString(TAG_WORKINGSET);
- if(wsname != null && workingSetFilter != null) {
- IWorkingSet set = getViewSite().getWorkbenchWindow().getWorkbench().getWorkingSetManager().getWorkingSet(wsname);
- if(set != null) {
- workingSetFilter.setWorkingSetName(wsname);
- }
+ if(wsname != null) {
+ IWorkingSetManager wsmanager = getViewSite().getWorkbenchWindow().getWorkbench().getWorkingSetManager();
+ IWorkingSet set = wsmanager.getWorkingSet(wsname);
+ wsFilterActionGroup.setWorkingSet(set);
+ } else {
+ wsFilterActionGroup.setWorkingSet(null);
}
- }
- void restoreState(IMemento memento) {
//ICelement container = CElementFactory.getDefault().getRoot();
CoreModel factory = CoreModel.getDefault();
IMemento childMem = memento.getChild(TAG_EXPANDED);
@@ -1268,7 +1207,7 @@
position = new Integer(posStr).intValue();
bar.setSelection(position);
} catch (NumberFormatException e){}
- }
+ }
}
public void saveState(IMemento memento) {
@@ -1342,9 +1281,12 @@
show= "false"; //$NON-NLS-1$
memento.putString(TAG_SHOWLIBRARIES, show);
- String wsname = workingSetFilter.getWorkingSetName();
- if(wsname != null) {
- memento.putString(TAG_WORKINGSET, wsname);
+ //Save the working set away
+ if(workingSetFilter.getWorkingSet() != null) {
+ String wsname = workingSetFilter.getWorkingSet().getName();
+ if(wsname != null) {
+ memento.putString(TAG_WORKINGSET, wsname);
+ }
}
}
}
Index: src/org/eclipse/cdt/internal/ui/editor/CEditor.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java,v
retrieving revision 1.24
diff -u -r1.24 CEditor.java
--- src/org/eclipse/cdt/internal/ui/editor/CEditor.java 28 Apr 2003 02:37:26 -0000 1.24
+++ src/org/eclipse/cdt/internal/ui/editor/CEditor.java 23 Jun 2003 19:18:40 -0000
@@ -794,4 +794,12 @@
protected void setOutlinerContextMenuId(String menuId) {
fOutlinerContextMenuId = menuId;
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes()
+ */
+ protected void initializeKeyBindingScopes() {
+ setKeyBindingScopes(new String [] { "org.eclipse.cdt.ui.cEditorScope" } );
+ }
+
}
Index: src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties,v
retrieving revision 1.4
diff -u -r1.4 CEditorMessages.properties
--- src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties 21 Apr 2003 17:05:46 -0000 1.4
+++ src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties 23 Jun 2003 19:18:40 -0000
@@ -110,11 +110,11 @@
Comment.label=&Comment
Comment.tooltip=Comment the Selected Lines
-Comment.description=Turn the selected lines into Java comments
+Comment.description=Turn the selected lines into C // style comments
Uncomment.label=Uncommen&t
-Uncomment.tooltip=Uncomment the Selected Java Comment Lines
-Uncomment.description=Uncomment the selected Java comment lines
+Uncomment.tooltip=Uncomment the Selected C // comment Lines
+Uncomment.description=Uncomment the selected C // comment lines
Format.label=F&ormat
Format.tooltip=Format the Selected Text
Index: src/org/eclipse/cdt/internal/ui/editor/DefaultCEditorTextHover.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/DefaultCEditorTextHover.java,v
retrieving revision 1.4
diff -u -r1.4 DefaultCEditorTextHover.java
--- src/org/eclipse/cdt/internal/ui/editor/DefaultCEditorTextHover.java 4 Feb 2003 20:00:46 -0000 1.4
+++ src/org/eclipse/cdt/internal/ui/editor/DefaultCEditorTextHover.java 23 Jun 2003 19:18:40 -0000
@@ -60,9 +60,14 @@
IFunctionSummary fs = CCompletionContributorManager.getDefault().getFunctionInfo(expression);
if(fs != null) {
- buffer.append("<b>" + HTMLPrinter.convertToHTMLContent(expression) +
- "()</b> - " + HTMLPrinter.convertToHTMLContent(fs.getSummary()) +
- "<br><br>" + HTMLPrinter.convertToHTMLContent(fs.getSynopsis()));
+ buffer.append("<b>");
+ buffer.append(HTMLPrinter.convertToHTMLContent(fs.getName()));
+ buffer.append("()</b>");
+ buffer.append(HTMLPrinter.convertToHTMLContent(fs.getPrototype().getPrototypeString(false)));
+ if(fs.getDescription() != null) {
+ buffer.append("<br><br>");
+ buffer.append(HTMLPrinter.convertToHTMLContent(fs.getDescription()));
+ }
int i;
for(i = 0; i < buffer.length(); i++) {
if(buffer.charAt(i) == '\\') {
Index: src/org/eclipse/cdt/internal/ui/text/CCompletionProcessor.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCompletionProcessor.java,v
retrieving revision 1.7
diff -u -r1.7 CCompletionProcessor.java
--- src/org/eclipse/cdt/internal/ui/text/CCompletionProcessor.java 13 Feb 2003 14:00:29 -0000 1.7
+++ src/org/eclipse/cdt/internal/ui/text/CCompletionProcessor.java 23 Jun 2003 19:18:41 -0000
@@ -20,6 +20,7 @@
import org.eclipse.cdt.internal.ui.text.template.TemplateEngine;
import org.eclipse.cdt.ui.CElementLabelProvider;
import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.FunctionPrototypeSummary;
import org.eclipse.cdt.ui.IFunctionSummary;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -28,6 +29,7 @@
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContextInformation;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
@@ -46,8 +48,10 @@
private CEditor fEditor;
private char[] fProposalAutoActivationSet;
private CCompletionProposalComparator fComparator;
- private TemplateEngine[] fTemplateEngine;
+ private IContextInformationValidator fValidator;
+ private TemplateEngine[] fTemplateEngine;
+
private boolean fRestrictToMatchingCase;
private boolean fAllowAddIncludes;
@@ -56,7 +60,7 @@
public CCompletionProcessor(IEditorPart editor) {
fEditor = (CEditor) editor;
-
+
//Determine if this is a C or a C++ file for the context completion + //This is _totally_ ugly and likely belongs in the main editor class.
String contextNames[] = new String[2];
ArrayList templateList = new ArrayList(2);
@@ -123,7 +127,10 @@
* @see IContentAssistProcessor#getContextInformationValidator()
*/
public IContextInformationValidator getContextInformationValidator() {
- return null;
+ if(fValidator == null) {
+ fValidator = new CParameterListValidator();
+ }
+ return fValidator;
}
/**
@@ -134,6 +141,13 @@
}
/**
+ * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+ */
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+ return null;
+ }
+
+ /**
* @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
*/
public char[] getCompletionProposalAutoActivationCharacters() {
@@ -151,13 +165,6 @@
}
/**
- * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
- */
- public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
- return null;
- }
-
- /**
* Tells this processor to restrict is proposals to those
* starting with matching cases.
*
@@ -238,14 +245,7 @@
* applies to all proposals and not just those of the compilation unit.
*/
order(results);
- if ((results.length == 1)
- && (CUIPlugin.getDefault().getPreferenceStore().getBoolean(ContentAssistPreference.AUTOINSERT))) {
- results[0].apply(document);
- // Trick the content assistant into thinking we have no proposals
- return new ICCompletionProposal[0];
- } else {
- return results;
- }
+ return results;
}
/**
@@ -256,102 +256,140 @@
return proposals;
}
- private void addProjectCompletions(IProject project, IRegion region, String frag, ArrayList completions) {
- IndexModel model = IndexModel.getDefault();
-
- ITagEntry[] tags = model.query(project, frag + "*", false, false);
- if (tags != null && tags.length > 0) {
- // We have some matches!
- for (int i = 0; i < tags.length; i++) {
-
- String fname = tags[i].getTagName();
-
- int kind = tags[i].getKind();
-
- if (kind == TagFlags.T_FUNCTION || kind == TagFlags.T_PROTOTYPE) {
- fname = fname + "()";
- }
- String proto = fname + " - " + tags[i].getPattern();
- //System.out.println("tagmatch " + fname + " proto " + proto + " type" + tags[i].getKind());
- if (tags[i].getKind() != TagFlags.T_MEMBER) {
- completions.add(new CCompletionProposal(fname, region.getOffset(), region.getLength(),
- //fname.length() + 1,
- getTagImage(kind), proto.equals("") ? (fname + "()") : proto,
- //null,
- //null));
- 3));
- }
- }
- }
- }
-
/**
* Evaluate the actual proposals for C
*/
private ICCompletionProposal[] evalProposals(IDocument document, int pos, int length) {
- IRegion region;
+ boolean isDereference = false;
+ IRegion region;
String frag = "";
-
+
// Move back the pos by one the position is 0-based
if (pos > 0) {
pos--;
}
- // First, check if we're on a space or trying to open a struct/union
+ // TODO: Check to see if we are trying to open for a structure/class, then
+ // provide that structure's completion instead of the function/variable
+ // completions. This needs to be properly dealt with so that we can
+ // offer completion proposals.
if (pos > 1) {
+ int struct_pos = pos;
+
try {
- // If we're on a space and the previous character is valid text,
- // parse the previous word.
- if (!Character.isJavaIdentifierPart(document.getChar(pos))) {
- pos--;
- if (!Character.isJavaIdentifierPart(document.getChar(pos))) {
- pos--;
- // Comment out the dereference code, only useful once we can
- // know variable types to go fish back structure members
- //if (document.getChar(offset) == '.') {
- // isDereference = true;
- // offset--;
- //} else if ((document.getChar(offset) == '>') && (document.getChar(offset - 1) == '-')) {
- // isDereference = true;
- // offset -= 2;
- //}
- }
+ //While we aren't on a space, then go back and look for
+ // . or a -> then determine the structure variable type.
+ while(document.getChar(struct_pos) == ' ') {
+ struct_pos--;
+ }
+
+ if (document.getChar(struct_pos) == '.') {
+ isDereference = true;
+ pos -= struct_pos - 1;
+ } else if ((document.getChar(struct_pos) == '>') && (document.getChar(struct_pos - 1) == '-')) {
+ isDereference = true;
+ pos -= struct_pos - 2;
+ } else {
+ isDereference = false;
}
- } catch (BadLocationException e) {
+ } catch (BadLocationException ex) {
return null;
}
}
- // Get the current "word"
+ // Get the current "word", it might be a variable or another starter
region = CWordFinder.findWord(document, pos);
-
- // If we're currently
+ if(region == null) {
+ return null; //Bail out on error
+ }
+
+ //@@@ TODO: Implement the structure member completion
+ if(isDereference) {
+ return null;
+ }
+
try {
- if (region != null) {
- frag = document.get(region.getOffset(), region.getLength());
- frag = frag.trim();
- // No word is selected
- if (frag.length() == 0) {
- return null;
+ frag = document.get(region.getOffset(), region.getLength());
+ frag = frag.trim();
+ } catch (BadLocationException ex) {
+ return null; //Bail out on error
+ }
+
+ //If there is no fragment, then see if we are in a function
+ if(frag.length() == 0) {
+ IRegion funcregion;
+ String funcfrag = "";
+
+ funcregion = CWordFinder.findFunction(document, pos + 1);
+ if(funcregion != null) {
+ try {
+ funcfrag = document.get(funcregion.getOffset(), funcregion.getLength());
+ funcfrag = funcfrag.trim();
+ } catch(Exception ex) {
+ funcfrag = "";
+ }
+ if(funcfrag.length() == 0) {
+ return null;
+ } else {
+ //@@@ Add some marker here to indicate different path!
+ region = funcregion;
+ frag = funcfrag;
}
- } else {
- return null;
}
- } catch (BadLocationException x) {
- // ignore
- return null;
}
+
// Based on the frag name, build a list of completion proposals
- // We look in two places: the content outline and the libs
-
ArrayList completions = new ArrayList();
// Look in index manager
+ addProposalsFromModel(region, frag, completions);
+
+ // Loot in the contributed completions
+ addProposalsFromCompletionContributors(region, frag, completions);
+
+ return (ICCompletionProposal[]) completions.toArray(new ICCompletionProposal[0]);
+ }
+
+ private void addProposalsFromCompletionContributors(IRegion region, String frag, ArrayList completions) {
+ IFunctionSummary[] summary;
+
+ summary = CCompletionContributorManager.getDefault().getMatchingFunctions(frag);
+ if(summary == null) {
+ return;
+ }
+
+ for (int i = 0; i < summary.length; i++) {
+ String fname = summary[i].getName() + "()";
+ String fdesc = summary[i].getDescription();
+ IFunctionSummary.IFunctionPrototypeSummary fproto = summary[i].getPrototype();
+ String fargs = fproto.getArguments();
+
+ CCompletionProposal proposal;
+ proposal = new CCompletionProposal(fname,
+ region.getOffset(),
+ region.getLength(),
+ getTagImage(TagFlags.T_FUNCTION),
+ fproto.getPrototypeString(true),
+ 2);
+
+ if(fdesc != null) {
+ proposal.setAdditionalProposalInfo(fdesc);
+ }
+
+ if(fargs != null && fargs.length() > 0) {
+ proposal.setContextInformation(new ContextInformation(fname, fargs));
+ }
+
+ completions.add(proposal);
+ }
+ }
+
+ private void addProposalsFromModel(IRegion region, String frag, ArrayList completions) {
IProject project = null;
IEditorInput input = fEditor.getEditorInput();
if (input instanceof IFileEditorInput) {
project = ((IFileEditorInput) input).getFile().getProject();
-
+
// Bail out quickly, if the project was deleted.
if (!project.exists()) {
project = null;
@@ -370,26 +408,54 @@
}
} catch (CoreException e) {
}
-
}
+ }
- IFunctionSummary[] summary;
+ private void addProjectCompletions(IProject project, IRegion region, String frag, ArrayList completions) {
+ IndexModel model = IndexModel.getDefault();
- //UserHelpFunctionInfo inf = plugin.getFunctionInfo();
- summary = CCompletionContributorManager.getDefault().getMatchingFunctions(frag);
- if (summary != null) {
- for (int i = 0; i < summary.length; i++) {
- String fname = summary[i].getName();
- String proto = summary[i].getPrototype();
- completions.add(new CCompletionProposal(fname + "()", region.getOffset(), region.getLength(),
- //fname.length() + 1,
- CPluginImages.get(CPluginImages.IMG_OBJS_FUNCTION), proto.equals("") ? (fname + "()") : proto,
- //null,
- //null));
- 2));
+ ITagEntry[] tags = model.query(project, frag + "*", false, false);
+ if (tags != null && tags.length > 0) {
+ for (int i = 0; i < tags.length; i++) {
+ String fname = tags[i].getTagName();
+ FunctionPrototypeSummary fproto = null;
+ int kind = tags[i].getKind();
+
+ if (kind == TagFlags.T_FUNCTION || kind == TagFlags.T_PROTOTYPE) {
+ fname = fname + "()";
+ }
+
+ if(tags[i].getPattern() != null) {
+ try {
+ fproto = new FunctionPrototypeSummary(tags[i].getPattern());
+ } catch(Exception ex) {
+ fproto = null;
+ }
+ }
+ if(fproto == null) {
+ fproto = new FunctionPrototypeSummary(fname);
+ }
+
+ //System.out.println("tagmatch " + fname + " proto " + proto + " type" + tags[i].getKind());
+ if (kind != TagFlags.T_MEMBER) {
+ CCompletionProposal proposal;
+ proposal = new CCompletionProposal(fname,
+ region.getOffset(),
+ region.getLength(),
+ getTagImage(kind),
+ fproto.getPrototypeString(true),
+ 3);
+ completions.add(proposal);
+
+ //No summary information available yet
+
+ String fargs = fproto.getArguments();
+ if(fargs != null && fargs.length() > 0) {
+ proposal.setContextInformation(new ContextInformation(fname, fargs));
+ }
+ }
}
}
- return (ICCompletionProposal[]) completions.toArray(new ICCompletionProposal[0]);
}
private Image getTagImage(int kind) {
Index: src/org/eclipse/cdt/internal/ui/text/CCompletionProposal.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCompletionProposal.java,v
retrieving revision 1.1
diff -u -r1.1 CCompletionProposal.java
--- src/org/eclipse/cdt/internal/ui/text/CCompletionProposal.java 26 Jun 2002 20:55:44 -0000 1.1
+++ src/org/eclipse/cdt/internal/ui/text/CCompletionProposal.java 23 Jun 2003 19:18:41 -0000
@@ -7,22 +7,22 @@
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.util.Assert;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
-
-public class CCompletionProposal implements ICCompletionProposal {
+public class CCompletionProposal implements ICCompletionProposal, ICompletionProposalExtension {
private String fDisplayString;
private String fReplacementString;
+ private String fAdditionalInfoString;
private int fReplacementOffset;
private int fReplacementLength;
private int fCursorPosition;
private Image fImage;
private IContextInformation fContextInformation;
private int fContextInformationPosition;
- //private ProposalInfo fProposalInfo;
//private IImportDeclaration fImportDeclaration;
private char[] fTriggerCharacters;
@@ -50,13 +50,20 @@
fDisplayString= displayString != null ? displayString : replacementString;
fRelevance= relevance;
- fCursorPosition= replacementString.length();
+ //@@@ Is this the best way to do this, likely it isn't
+ if(replacementString.indexOf("()") == -1) { //Not replacing with a function
+ fCursorPosition = replacementString.length();
+ } else if(displayString.indexOf("()") == -1) { //Assume that there are arguments between ()
+ fCursorPosition = replacementString.length() - 1;
+ } else {
+ fCursorPosition = replacementString.length();
+ }
+ fAdditionalInfoString = null;
fContextInformation= null;
fContextInformationPosition= -1;
//fIncludeDeclaration= null;
fTriggerCharacters= null;
- //fProposalInfo= null;
}
/**
@@ -86,14 +93,6 @@
}
/**
- * Sets the proposal info.
- * @param additionalProposalInfo The additional information associated with this proposal or <code>null</code>
- *
- public void setProposalInfo(ProposalInfo proposalInfo) {
- fProposalInfo= proposalInfo;
- }*/
-
- /**
* Sets the cursor position relative to the insertion offset. By default this is the length of the completion string
* (Cursor positioned after the completion)
* @param cursorPosition The cursorPosition to set
@@ -146,22 +145,49 @@
}
} */
}
+
+ /*
+ * @see ICompletionProposal#apply
+ */
+ public void apply(IDocument document) {
+ apply(document, (char) 0, fReplacementOffset + fReplacementLength);
+ }
/*
+ * In this case we need to apply the completion proposal intelligently.
+ * This means that if we are applying it to a function, we don't wipe
+ * out the internal arguments, and if the proposal is a function, and it
+ * already is bracketed, then don't put those brackets in.
+ *
* @see ICompletionProposalExtension#apply(IDocument, char, int)
*/
public void apply(IDocument document, char trigger, int offset) {
+ int functionBracketIndex;
+ boolean isBeforeBracket;
+ String replacementStringCopy = fReplacementString;
+
+ //If just providing context information, then don't move the cursor
+ if(offset != (fReplacementOffset + fReplacementLength)) {
+ fCursorPosition = offset - fReplacementOffset;
+ }
+
try {
+ functionBracketIndex = fReplacementString.indexOf("()");
+ isBeforeBracket = document.getChar(fReplacementOffset + fReplacementLength) == '(';
- // patch replacement length
- int delta= offset - (fReplacementOffset + fReplacementLength);
- if (delta > 0)
- fReplacementLength += delta;
-
+ //Strip the brackets off the function if inserting right before brackets
+ if(functionBracketIndex != -1 && isBeforeBracket) {
+ replacementStringCopy = fReplacementString.substring(0, functionBracketIndex);
+ }
+ } catch(Exception ex) {
+ /* Ignore */
+ }
+
+ try {
if (trigger == (char) 0) {
- replace(document, fReplacementOffset, fReplacementLength, fReplacementString);
+ replace(document, fReplacementOffset, fReplacementLength, replacementStringCopy);
} else {
- StringBuffer buffer= new StringBuffer(fReplacementString);
+ StringBuffer buffer= new StringBuffer(replacementStringCopy);
// fix for PR #5533. Assumes that no eating takes place.
if ((fCursorPosition > 0 && fCursorPosition <= buffer.length() && buffer.charAt(fCursorPosition - 1) != trigger)) {
@@ -172,6 +198,12 @@
replace(document, fReplacementOffset, fReplacementLength, buffer.toString());
}
+ /*
+ * The replacement length is used to calculate the new cursor position,
+ * so after we update the includes adjust the replacement offset.
+ * NOTE: This won't work if the include is added after the offset,
+ * such as might be the case with #include completions.
+ */
int oldLen= document.getLength();
applyIncludes(document);
fReplacementOffset += document.getLength() - oldLen;
@@ -186,13 +218,6 @@
if (!document.get(offset, length).equals(string))
document.replace(offset, length, string);
}
-
- /*
- * @see ICompletionProposal#apply
- */
- public void apply(IDocument document) {
- apply(document, (char) 0, fReplacementOffset + fReplacementLength);
- }
/*
* @see ICompletionProposal#getSelection
@@ -222,14 +247,20 @@
return fDisplayString;
}
+ /**
+ * Set the additional information which will be shown when this
+ * proposal is selected in the popup list.
+ * @param infoString
+ */
+ public void setAdditionalProposalInfo(String infoString) {
+ fAdditionalInfoString = infoString;
+ }
+
/*
* @see ICompletionProposal#getAdditionalProposalInfo()
*/
public String getAdditionalProposalInfo() {
- //if (fProposalInfo != null) {
- // return fProposalInfo.getInfo();
- //}
- return null;
+ return fAdditionalInfoString;
}
/*
@@ -245,6 +276,27 @@
public int getContextInformationPosition() {
return fReplacementOffset + fContextInformationPosition;
}
+
+ /*
+ * @see ICompletionProposalExtension#isValidFor(IDocument, int)
+ */
+ public boolean isValidFor(IDocument document, int offset) {
+ if (offset < fReplacementOffset)
+ return false;
+
+ int replacementLength= fReplacementString == null ? 0 : fReplacementString.length();
+ if (offset >= fReplacementOffset + replacementLength)
+ return false;
+
+ try {
+ int length= offset - fReplacementOffset;
+ String start= document.get(fReplacementOffset, length);
+ return fReplacementString.substring(0, length).equalsIgnoreCase(start);
+ } catch (BadLocationException x) {
+ }
+
+ return false;
+ }
/**
* Gets the replacement offset.
@@ -302,28 +354,6 @@
*/
public void setImage(Image image) {
fImage= image;
- }
-
- /*
- * @see ICompletionProposalExtension#isValidFor(IDocument, int)
- */
- public boolean isValidFor(IDocument document, int offset) {
-
- if (offset < fReplacementOffset)
- return false;
-
- int replacementLength= fReplacementString == null ? 0 : fReplacementString.length();
- if (offset >= fReplacementOffset + replacementLength)
- return false;
-
- try {
- int length= offset - fReplacementOffset;
- String start= document.get(fReplacementOffset, length);
- return fReplacementString.substring(0, length).equalsIgnoreCase(start);
- } catch (BadLocationException x) {
- }
-
- return false;
}
/**
Index: src/org/eclipse/cdt/internal/ui/text/CParameterListValidator.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/text/CParameterListValidator.java
diff -N src/org/eclipse/cdt/internal/ui/text/CParameterListValidator.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/text/CParameterListValidator.java 23 Jun 2003 19:18:41 -0000
@@ -0,0 +1,216 @@
+package org.eclipse.cdt.internal.ui.text;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+
+/**
+ * This class provides the function parameter parsing for the C/C++ Editor hover
+ * It is based heavily on the Java class JavaParameterListValidator
+ *
+ * @author thomasf
+ *
+ */
+public class CParameterListValidator implements IContextInformationValidator, IContextInformationPresenter {
+ private int fPosition;
+ private ITextViewer fViewer;
+ private IContextInformation fInformation;
+
+ private int fCurrentParameter;
+
+ public CParameterListValidator() {
+ }
+
+ /**
+ * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
+ * @see IContextInformationPresenter#install(IContextInformation, ITextViewer, int)
+ */
+ public void install(IContextInformation info, ITextViewer viewer, int documentPosition) {
+
+ fPosition= documentPosition;
+ fViewer= viewer;
+ fInformation= info;
+
+ fCurrentParameter= -1;
+ }
+
+ private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
+ while (pos < end) {
+ char curr= d.getChar(pos);
+ pos++;
+ if (curr == '*') {
+ if (pos < end && d.getChar(pos) == '/') {
+ return pos + 1;
+ }
+ }
+ }
+ return end;
+ }
+
+ private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
+ while (pos < end) {
+ char curr= d.getChar(pos);
+ pos++;
+ if (curr == '\\') {
+ // ignore escaped characters
+ pos++;
+ } else if (curr == ch) {
+ return pos;
+ }
+ }
+ return end;
+ }
+
+ private int getCharCount(IDocument document, int start, int end,
+ char increment, char decrement, boolean considerNesting) throws BadLocationException {
+
+ Assert.isTrue((increment != 0 || decrement != 0) && increment != decrement);
+
+ int nestingLevel= 0;
+ int charCount= 0;
+ while (start < end) {
+ char curr= document.getChar(start++);
+ switch (curr) {
+ case '/':
+ if (start < end) {
+ char next= document.getChar(start);
+ if (next == '*') {
+ // a comment starts, advance to the comment end
+ start= getCommentEnd(document, start + 1, end);
+ } else if (next == '/') {
+ // '//'-comment: nothing to do anymore on this line
+ start= end;
+ }
+ }
+ break;
+ case '*':
+ if (start < end) {
+ char next= document.getChar(start);
+ if (next == '/') {
+ // we have been in a comment: forget what we read before
+ charCount= 0;
+ ++ start;
+ }
+ }
+ break;
+ case '"':
+ case '\'':
+ start= getStringEnd(document, start, end, curr);
+ break;
+ default:
+
+ if (considerNesting) {
+
+ if ('(' == curr)
+ ++ nestingLevel;
+ else if (')' == curr)
+ -- nestingLevel;
+
+ if (nestingLevel != 0)
+ break;
+ }
+
+ if (increment != 0) {
+ if (curr == increment)
+ ++ charCount;
+ }
+
+ if (decrement != 0) {
+ if (curr == decrement)
+ -- charCount;
+ }
+ }
+ }
+
+ return charCount;
+ }
+
+ /**
+ * @see IContextInformationValidator#isContextInformationValid(int)
+ */
+ public boolean isContextInformationValid(int position) {
+
+ try {
+ if (position < fPosition)
+ return false;
+
+ IDocument document= fViewer.getDocument();
+ IRegion line= document.getLineInformationOfOffset(fPosition);
+
+ if (position > line.getOffset() + line.getLength())
+ return false;
+
+ return (getCharCount(document, fPosition, position, '(', ')', false) >= 0);
+
+ } catch (BadLocationException x) {
+ return false;
+ }
+ }
+
+ /**
+ * @see IContextInformationPresenter#updatePresentation(int, TextPresentation)
+ */
+ public boolean updatePresentation(int position, TextPresentation presentation) {
+
+ int currentParameter= -1;
+
+ try {
+ currentParameter= getCharCount(fViewer.getDocument(), fPosition, position, ',', (char) 0, true);
+ } catch (BadLocationException x) {
+ return false;
+ }
+
+ if (fCurrentParameter != -1) {
+ if (currentParameter == fCurrentParameter)
+ return false;
+ }
+
+ presentation.clear();
+ fCurrentParameter= currentParameter;
+
+ String s= fInformation.getInformationDisplayString().trim();
+
+ int start= 0;
+ int occurrences= 0;
+ while (occurrences < fCurrentParameter) {
+ int found= s.indexOf(',', start);
+ if (found == -1)
+ break;
+ start= found + 1;
+ ++ occurrences;
+ }
+
+ if (occurrences < fCurrentParameter) {
+ presentation.addStyleRange(new StyleRange(0, s.length(), null, null, SWT.NORMAL));
+ return true;
+ }
+
+ if (start == -1)
+ start= 0;
+
+ int end= s.indexOf(',', start);
+ if (end == -1)
+ end= s.length();
+
+ if (start > 0)
+ presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL));
+
+ if (end > start)
+ presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD));
+
+ if (end < s.length())
+ presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL));
+
+ return true;
+ }
+}
+
Index: src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java,v
retrieving revision 1.10
diff -u -r1.10 CSourceViewerConfiguration.java
--- src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java 29 Jan 2003 18:18:30 -0000 1.10
+++ src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java 23 Jun 2003 19:18:41 -0000
@@ -26,6 +26,7 @@
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.formatter.ContentFormatter;
import org.eclipse.jface.text.formatter.IContentFormatter;
@@ -158,7 +159,6 @@
reconciler.setDamager(dr, CPartitionScanner.C_MULTILINE_COMMENT);
reconciler.setRepairer(dr, CPartitionScanner.C_MULTILINE_COMMENT);
-
return reconciler;
}
@@ -167,15 +167,30 @@
* @see SourceViewerConfiguration#getContentAssistant(ISourceViewer)
*/
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+ if(getEditor() == null) {
+ return null;
+ }
+
ContentAssistant assistant = new ContentAssistant();
- // IFile file = (sourceViewer).
- assistant.setContentAssistProcessor(new CCompletionProcessor(fEditor), IDocument.DEFAULT_CONTENT_TYPE);
+
+ IContentAssistProcessor processor = new CCompletionProcessor(getEditor());
+ assistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
+
+ //Will this work as a replacement for the configuration lines below?
+ //ContentAssistPreference.configure(assistant, getPreferenceStore());
+
+ assistant.enableAutoInsert(CUIPlugin.getDefault().getPreferenceStore().getBoolean(ContentAssistPreference.AUTOINSERT));
assistant.enableAutoActivation(true);
assistant.setAutoActivationDelay(500);
assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
+
+ assistant.setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE);
+ assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
+
return assistant;
}
+
/**
* @see SourceViewerConfiguration#getReconciler(ISourceViewer)
*/
@@ -367,7 +382,7 @@
public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer, final boolean cutDown) {
return new IInformationControlCreator() {
public IInformationControl createInformationControl(Shell parent) {
- int style= cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
+ int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
return new DefaultInformationControl(parent, style, new HTMLTextPresenter(cutDown));
// return new HoverBrowserControl(parent);
}
Index: src/org/eclipse/cdt/internal/ui/text/CWordFinder.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CWordFinder.java,v
retrieving revision 1.1
diff -u -r1.1 CWordFinder.java
--- src/org/eclipse/cdt/internal/ui/text/CWordFinder.java 26 Jun 2002 20:55:44 -0000 1.1
+++ src/org/eclipse/cdt/internal/ui/text/CWordFinder.java 23 Jun 2003 19:18:41 -0000
@@ -10,9 +10,31 @@
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
-
+/**
+ * This is a helper class for the text editor to be able to determine,
+ * given a particular offset in a document, various candidates segments
+ * for things like context help, proposals and hovering.
+ */
public class CWordFinder
{
+ /**
+ * This method determines for a given offset into a given document
+ * what the region is which defines the current word. A word is
+ * defined as the set of non "C" identifiers. So assuming that !
+ * indicated the current cursor postion:
+ * !afunction(int a, int b) --> word = length 0
+ * afunc!tion(int a, int b) --> word = afunction
+ * afunction!(int a, int b) --> word = afunction
+ * afunction(!int a, int b) --> word = length 0
+ * afunction(int a,! int b) --> word = length 0
+ * afunction(!) --> word = length 0
+ * @param document The document to be examined
+ * @param offset The offset into the document where a word should
+ * be idendified.
+ * @return The region defining the current word, which may be a
+ * region of length 0 if the offset is not in a word, or null if
+ * there is an error accessing the docment data.
+ */
public static IRegion findWord( IDocument document, int offset )
{
int start = -1;
@@ -63,6 +85,121 @@
return null;
}
+
+ /**
+ * This method will determine the region for the name of the function
+ * within which the current offset is contained.
+ * @param document The document to be examined
+ * @param offset The offset into the document where a word should
+ * be idendified.
+ * @return The region defining the current word, which may be a
+ * region of length 0 if the offset is not in a function, or null if
+ * there is an error accessing the docment data.
+ */
+ public static IRegion findFunction( IDocument document, int offset )
+ {
+ int leftbracket = -1;
+ int leftbracketcount = 0;
+ int rightbracket = -1;
+ int rightbracketcount = 0;
+ int functionstart = -1;
+ int functionend = -1;
+
+
+ try
+ {
+ int length = document.getLength();
+ int pos;
+ char c;
+
+ //Find most relevant right bracket from our position
+ pos = offset;
+ rightbracketcount = leftbracketcount = 0;
+ while(pos < length) {
+ c = document.getChar( pos );
+
+ if( c == ')') {
+ rightbracketcount++;
+ if(rightbracketcount >= leftbracketcount) {
+ rightbracket = pos;
+ break;
+ }
+ }
+
+ if(c == '(') {
+ leftbracketcount++;
+ }
+
+ if(c == ';') {
+ break;
+ }
+
+ pos++;
+ }
+
+ if ( rightbracket == -1 ) {
+ return new Region(offset, 0);
+ }
+
+ //Now backtrack our way from the rightbracket to the left
+ pos = rightbracket;
+ rightbracketcount = leftbracketcount = 0;
+ while(pos >= 0) {
+ c = document.getChar( pos );
+
+ if( c == ')') {
+ rightbracketcount++;
+ }
+
+ if(c == '(') {
+ leftbracketcount++;
+ if(leftbracketcount >= rightbracketcount) {
+ leftbracket = pos;
+ break;
+ }
+ }
+
+ if(c == ';') {
+ break;
+ }
+
+ pos--;
+ }
+
+ if ( leftbracket == -1 ) {
+ return new Region(offset, 0);
+ }
+
+ //Now work our way to the function name
+ pos = leftbracket - 1;
+ while(pos >= 0) {
+ c = document.getChar( pos );
+ if(functionend == -1 && c == ' ' ) {
+ continue;
+ }
+
+ if(!Character.isJavaIdentifierPart(c)) {
+ break;
+ }
+
+ functionstart = pos;
+ if(functionend == -1) {
+ functionend = pos;
+ }
+
+ pos--;
+ }
+ } catch( BadLocationException x ) {
+ /* Ignore */
+ }
+
+ if (functionstart > -1 && functionend > -1) {
+ return new Region(functionstart, functionend - functionstart + 1);
+ }
+
+ return null;
+ }
+
}
Index: src/org/eclipse/cdt/ui/FunctionPrototypeSummary.java
===================================================================
RCS file: src/org/eclipse/cdt/ui/FunctionPrototypeSummary.java
diff -N src/org/eclipse/cdt/ui/FunctionPrototypeSummary.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/ui/FunctionPrototypeSummary.java 23 Jun 2003 19:18:41 -0000
@@ -0,0 +1,69 @@
+package org.eclipse.cdt.ui;
+
+/**
+ * This class is a helper class which takes care of implementing some of the
+ * function prototype parsing and stripping.
+ */
+public class FunctionPrototypeSummary implements IFunctionSummary.IFunctionPrototypeSummary {
+ String fname;
+ String freturn;
+ String farguments;
+
+ /**
+ * Creates a prototype which matches the format
+ * returntype function(arguments)
+ * @param properProto
+ */
+ public FunctionPrototypeSummary(String proto) {
+ int leftbracket = proto.indexOf('(');
+ int rightbracket = proto.lastIndexOf(')');
+ farguments = proto.substring(leftbracket + 1, rightbracket);
+
+ int nameend = leftbracket - 1;
+ while(proto.charAt(nameend) == ' ') {
+ nameend--;
+ }
+ int namestart = nameend;
+ while(namestart > 0 && proto.charAt(namestart) != ' ') {
+ namestart--;
+ }
+ fname = proto.substring(namestart, nameend + 1).trim();
+
+ if(namestart == 0) {
+ freturn = "void";
+ } else {
+ freturn = proto.substring(0, namestart).trim();
+ }
+ }
+
+ public String getName() {
+ return fname;
+ }
+
+ public String getReturnType() {
+ return freturn;
+ }
+
+ public String getArguments() {
+ return farguments;
+ }
+
+ public String getPrototypeString(boolean namefirst) {
+ StringBuffer buffer = new StringBuffer();
+ if(!namefirst) {
+ buffer.append(getArguments());
+ buffer.append(" ");
+ }
+ buffer.append(getName());
+ buffer.append("(");
+ if(getArguments() != null) {
+ buffer.append(getArguments());
+ }
+ buffer.append(")");
+ if(namefirst) {
+ buffer.append(" ");
+ buffer.append(getReturnType());
+ }
+ return buffer.toString();
+ }
+}
Index: src/org/eclipse/cdt/ui/IFunctionSummary.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/IFunctionSummary.java,v
retrieving revision 1.1
diff -u -r1.1 IFunctionSummary.java
--- src/org/eclipse/cdt/ui/IFunctionSummary.java 26 Jun 2002 20:55:44 -0000 1.1
+++ src/org/eclipse/cdt/ui/IFunctionSummary.java 23 Jun 2003 19:18:41 -0000
@@ -7,28 +7,72 @@
public interface IFunctionSummary {
- /**
- * Get the name of the function
- */
- public String getName();
+ public interface IFunctionPrototypeSummary {
+ /**
+ * Get the name of the function. This should be the
+ * same as for IFunctionSummary.
+ * ie "int main(int argc, char **argv)" --> "main"
+ * @return The name of the function without any additional
+ * information.
+ */
+ public String getName();
+
+ /**
+ * Get the return type of the function.
+ * ie "int main(int argc, char **argv)" --> "int"
+ * @return A string containing the return type of the
+ * function.
+ */
+ public String getReturnType();
+
+ /**
+ * Get the arguments of the function.
+ * ie "int main(int argc, char **argv)" --> "int argc, char **argv"
+ * @return A string containing the arguments of the
+ * function, or null if the function has no arguments.
+ */
+ public String getArguments();
+
+ /**
+ * Get a nice user defined string. The format of
+ * which depends on the variable namefirst
+ * namefirst == true: main(int argc, char **argv) int
+ * namefirst == false: int main(int argc, char **argv);
+ * @return
+ */
+ public String getPrototypeString(boolean namefirst);
+ }
/**
- * Get the function summary
+ * Gets the name of the function. This is the simple
+ * name without any additional return or argument information.
+ * The function "int main(int argc, char **argv)" would
+ * return "main"
+ * @return The name of the function without any additional
+ * information
*/
- public String getSummary();
+ public String getName();
/**
- * Get the function prototype
+ * Gets the description of the function. This string can be
+ * either text or HTML coded and is displayed as part of the
+ * hover help and as the context proposal information.
+ * @return A description for this function, or null if no
+ * description is available.
*/
- public String getPrototype();
+ public String getDescription();
/**
- * Get the function synopsis
+ * Gets the prototype description for this function.
+ * @return The IFunctionPrototypeSummary describing the
+ * prototype for this function
*/
- public String getSynopsis();
-
+ public IFunctionPrototypeSummary getPrototype();
+
/**
* Get headers required by this function
+ * @return A list of IRequiredInclude definitions, or null if no
+ * include definitions are available.
*/
public IRequiredInclude[] getIncludes();
}