Currently I am developing a plugin for Eclipse CDT. I have successfully made an action declaration in my plugin.xml file.
<extension
point="org.eclipse.ui.popupMenus">
<objectContribution
id="MyOwnPlugin.contribution1"
nameFilter="*.c"
objectClass="org.eclipse.ui.IEditorInput">
<action
class="myownplugin.popup.actions.DoTestsAction"
enablesFor="1"
id="myownplugin.doTests"
label="Do Tests"
menubarPath="additions">
</action>
</objectContribution>
</extension>
This successfully declares a popup action when I right-click on the editor and I can select the action.
However, what I would like to achieve is that the action would only appear when I right-click on a function name/function declaration. Is there a way how to achieve this? I have been trying the filter XML tag in the plugin.xml, but with no success.
Thanks.
I haven't tried this myself, but I believe what you want is doable (modulo the click position vs. caret position issue described in the comments). You are on the right track with using the <filter> element, but there are some other pieces required to get this to work.
The first thing to realize is that a context menu pertains to an object, and in the case of the editor's context menu, that object is the IEditorInput representing the contents of the editor tab.
Any mechanism to make the presence of a context menu action dependent on some condition, will only have that object available as input. It follows that the condition must be based on the state of the object (only). This is why we can base it on caret position but not on the location of the click itself: "the current caret position in the editor" is part of the state of the IEditorInput, but "the location of the current click within the editor" is not (that I know of).
The documentation of the <filter> element says:
This element is used to evaluate the attribute state of each object
in the current selection. A match only if each object in the selection
has the specified attribute state. Each object in the selection must
implement, or adapt to, org.eclipse.ui.IActionFilter.
The reason this talks about a "selection" is that in some views a context menu can be invoked with multiple objects selected (e.g. in the Project Explorer view, with multiple files / folders selected). In an editor context that doesn't apply; there will only be one object in the "selection", of type IEditorInput.
Unfortunately, IEditorInput does not implement IActionFilter. However, it does implement IAdaptable, so we can use the adapter mechanism to have our plugin support adapting it to IActionFilter.
That will involve adding something like this to your plugin.xml:
<extension point="org.eclipse.core.runtime.adapters">
<factory
class="your.plugin.EditorInputAdapterFactory"
adaptableType="org.eclipse.ui.IEditorInput">
<adapter type="org.eclipse.ui.IActionFilter"/>
</factory>
</extension>
where your.plugin.EditorInputAdapterFactory is a type you'll write in your plugin. Its implementation will look something like this:
public class EditorInputAdapterFactory implements IAdapterFactory {
#Override
public <T> T getAdapter(Object adaptable, Class<T> adapterType) {
if (adaptable instanceof IEditorInput && adapterType.equals(IActionFilter.class)) {
return new EditorInputActionFilter((IEditorInput) adaptable);
}
return null;
}
}
where EditorInputActionFilter is, again, a type we'll write.
Ok, now we have an action filter that works with IEditorInput objects, enabling us to use the <filter> element.
The <filter> element uses an "attribute name" and an "attribute value", which will be passed it to the IActionFilter. As the author of the action filter, we get to invent these. For example, we can invent an attribute name called selectedElementType (where by "selected element" I mean the type of C++ element the caret is currently over), and a value named function.
Then our filter declaration will look like this:
<filter name="selectedElementType" value="function" />
Finally, we need to implement our action filter so it evaluates the property we defined for an IEditorInput object. I won't write up the complete implementation here, but in broad strokes:
Use CDTUITools.getWorkingCopyManager() to map the IEditorInput to an IWorkingCopy, which implements ITranslationUnit.
Get the editor's current caret position, using something like CUIPlugin.getActivePage().findEditor(editorInput).getEditorSite().getSelectionProvider().getSelection() (with appropriate null checks in between). There may be an easier way to do this, but that's what comes to mind. Since you're in an editor, the returned selection should have type ITextSelection.
Use SharedASTJob to get access to the editor's shared AST (IASTTranslationUnit). Note that you'll need to block on the job, and the action filter will (I assume) be invoked on the UI thread, which is not ideal. (More on that below.)
Use IASTTranslationUnit.getNodeSelector(null).findEnclosingName(offset, length), with the offset and length from the ITextSelection, to get an IASTName representing the name under the caret (if any).
Use IASTName.resolveBinding() to get the binding (C++ semantic model object) that the name refers to.
Check if the binding implements IFunction.
All of this will go in your implementation of IActionFilter.testAttribute(). The target parameter to that function will be the IEditorInput. For good measure, you should check that the name and value parameters correspond to the attribute names you invented (selectedElementType and function) before doing any of this (initially, your action filter will only be invoked by your <filter> element, so they'll always match, but you can imagine extending this mechanism in the future to e.g. support other selected element types.)
Finally, a note on performance: what you're doing here is conditioning the responsiveness of a UI element (the appearance of a popup) on a property of C++ code, which can be slow to parse and analyze. This necessarily means your popup may take longer to appear as a result (which is reflected in your action filter needing to block on the SharedASTJob). By using SharedASTJob, you are minimizing this effect by re-using an already-parsed AST if there is one, but e.g. if you've just opened an editor and you right-click, and the initial AST takes several seconds to build, your popup will take several seconds to show up. Caveat emptor.
Related
When I use ctrl+shift+G to find references for an object in eclipse, I will get a list of those, but they are collapsed like this:
Why being collapsed?
Those four occurences are method calls on the object. I expect to be able to see which method calls that are called on the object by looking in this list. Can that be made?
Matches within a single method in a class are always just shown as 'n matches'. There is no way to expand this in the search results view (see Eclipse bug 46051).
I'm using Intellij IDEA 13 for android development.
Some methods has long list of parameters. For example, db.query(...) and I can't remember the order of them.
Is there any plugin or can i change some settings to make IDEA insert variables from function template?
Thanks
You have a couple of options. Ctrl+P will show a lit of the parameters, with the current one bolded. As long as you have either the source or javadoc for the library (or JDK/SDK) attached to the corresponding definition, you will see the parameters' names.
If you invoke code completion while entering parameters, IDEA will show at the top only ones that are of the correct type. Furthermore, if one of you local variables is the same name (or similar to) the required parameter's name, it will be at the top of the list. So if there is a method that takes an int named 'width', and I have several int variables, but one is named 'theWidth', it would be at the top. (Again, this assumes you have javadoc or source attached so IDEA can determine parameter names.) If IDEA can find local variables that satisfy all parameters (or all the first x parameters) of the method, there will be an option in the code completion list to complete all of them, The icon will be a double circle. The below screen shot shows how the HttpServletReqest is at the top of the list. So I do not have to remember if the parameter order is "request, response" or "response, "request". Notice the fourth option is to complete both the request and the response.
I am developing an Eclipse RCP application and have defined a custom context (org.eclipse.ui.contexts) for my editors. This context is activated whenever I invoke one of my editors.
Further, I have defined a single-key key binding (org.eclipse.ui.bindings) that I have scoped to this context which, when typed within the editor context, invokes a command/handler (I'll use the letter 'J' for this example).
Everything works as expected. When I launch/select one of my custom editors, the context is activated and 'J' executes my handler. When I launch/select a view part, my custom editor's context is deactivated and 'J' no longer executes the handler. However, when I click in a Text widget somewhere in the window trim area--let's say the Quick Access field--and type the letter 'J', the keystroke is consumed and executes my handler, behavior I do NOT want.
The reason is that selecting another workbench part has the effect of activating its context and deactivating the previous one. However clicking anywhere else in the workbench window area (other than another part) does NOT deactivate the previous context. I am sure this is by design and is a perfectly reasonable approach. However, it prevents me from defining single-key key bindings.
Has anyone a) run into this problem before and b) if so, how did you solve it?
For now I am using a complete hack that involves using a global listener to disable the key binding service entirely on detecting entry into a Text widget, and re-enabling it on exit from the Text widget.
In extension point point <extension point="org.eclipse.ui.bindings"> do not specify the command ID that will replace the existing key.
See the documentation for details.
commandId - The unique identifier of the command to which the key sequence specified by this key binding is assigned. If the value of this attribute is an empty string, the key sequence is assigned to an internal 'no operation' command. This is useful for 'undefining' key bindings in specific key configurations and contexts which may have been borrowed from their parents.
Currently I get this result with Eclipse auto completion.
System.console().printf(format, args)
Of course, Eclipse shows the parameter types as popup, but I want the types to be displayed in front of parameter names too. Like this.
System.console().printf(String format, Object ... args) // `String`, `Object` inserted automatically.
Can I configure Eclipse to show the parameter types too?
Of course not. Eclipse auto completion only suggests valid syntax, while your demand is not valid java code.
An alternative for you might be to open the "Declaration" view or the "JavaDoc" view. Both will always show the declaration/JavaDoc of the currently selected element while you are typing. Therefore you could see the method declaration/javadoc when writing that method call.
Update
Whoever came across this old question. You can use eclipse code mining now:
parameter name hint for Eclipse
When I click on a variable, object etc in eclipse and choose "References --> Project" from the context menu, I am presented with a list of methods which reference said object. However if a function has more than one reference the result is shown as:
functionName(signature) (x matches)
Double clicking on the result brings me to the first match, and there appears to be no way to locate the remaining matches. What am I doing wrong?
Use the buttons with the up/down arrows in the search view, they will bring you to the previous/next search result, independent of the code structure, file location etc.
There is no way to further expand the tree of search results for a Java method.