How do I disable single-key key bindings in Eclipse Text widgets - eclipse

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.

Related

Eclipse CDT plugin - action restricted to function name

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.

Trigger hover-like tooltip in vscode

I want to develop an extension functionality where user can request a type of given expression by a pressing a combination of keys instead of just hovering.
The key moment here is that when the same combination is pressed again, I want to increase the scope of selection and show the type of the "bigger" block, etc.
I have the functionality ready in my language client, so I have a command and receive the response. I can also decorate the expression I want to display type for, this works well.
But how do I implement triggering hover-like tooltip to actually show the type?

Multiple handlers for one command in eclipse e4

I am writing a new command for my eclipse RCP that should perform one task if one part is active, and other task if other task is active (eg. copy command that copies files if project explorer is active or copies text if text editor is active). I was thinking of having 2 handlers for one command (one defined in fragment.e4xmi of one plugin and other handler in fragment.e4xmi of another plugin). Is this doable?
On this page http://www.vogella.com/tutorials/EclipseRCP/article.html#importantmodelelement_examples it says that:
Each command can have only one valid handler for a given scope. The Eclipse framework selects the handler most specific to the model element.
For example, if you have two handlers for the "Copy" command, one for the window and another one for the part then the runtime selects the handlers closest to model element which is currently selected by the user.
Is it possible to have 2 handlers for one command in e4?
If you mean two handlers being called for one invocation of the command the answer is No.
As the reference you quote says the handler closest to the current model element is chosen.
For multiple handlers applying to different parts put each handler in the Handlers list for the part you want it to apply to. This can be in a fragment or the main e4xmi file.

Eclipse caret jumps to constructor while typing

While typing in Eclipse (Java) I often have the problem that when I begin to type accessors, the caret jumps down to the beginning of the constructor definition. So in a document like this:
private int mSomeInt;
public
in|public MyClass(){
}
I would like to manually type out the accessor (getter/setter) for mSomeInt, but when I press space after 'public' above, the caret jumps to the beginning of 'public MyClass'.
I often type complete lines to look up and find my methods jumbled with the constructor (like above).
Any help would be appreciated.
Note - this isn't only with accessors but rather any access modifiers that I define before the constructor or another method.
Edit
After unsuccessfully trying Deco's solution below, I've managed to narrow it down a little further.
The problem only happens if I have all the blocks in the file in a collapsed state (ctrl+shift+numPadDivide). I can see the problem is now that the new access modifier I type is then (quickly) collapsed into the below method. i.e. Eclipse is actually taking the first accessor modifier and collapsing everything from there, even though my intention is actually to write a new method.
The only solution I've been able to find is to only edit the source with all the 'fold' elements unfolded.
Under Window -> Preferences -> <Language> (e.g. Java) -> Editor there is a Content Assist menu item where you can configure auto completion and caret placement as well as auto-activation of it and the delay it uses.
Edit:
After your update to the original question I was able to successfully replicate this in Eclipse Indigo. When you have all of the code blocks collapsed it looks like Eclipse assumes that the code you are writing needs to be in that block (rather than as a variable declaration). I'm not sure if this is expected behaviour or not - but the only way around it I've found is to edit the code with the main block open, and then close it after the fact - or turn folding off altogether.
From what I can tell there are various folding plugins/addons that you can get for Eclipse which override the default behaviour and might function better? A quick Google search will be able to get you a list of them quickly.
I'd probably also suggest posting this as an issue on the Eclipse support site for their official answer.
Unfortunately this issue still exists for me in the latest Elcipse version (Kepler).
As the issue only occurs when the document is 'folded', the work around this is to either disable folding in the editor - or disable folding on 'Members' from the :
Preferences -> Java -> Editor -> Folding

Missing link between objectContribution and command

When using the objectContribution-element (which is part of the org.eclipse.ui.popupMenus-extension point), I often (practically always) want to delegate to some command instead of implementing some action myself (since usually, I have the command and a handler already implemented). I'm doing this by using ICommandService and IHandlerService, but it feels there should be a way to achieve this programmatically. I could use viewerContribution instead of objectContribution, but then I would lose the easy way of showing the menu entry only when certain object types are selected. Ideally, I would like to use the enablement-checks that already exist for my handlers to apply to the menu entry defined by the objectContribution.
Ok, here's what I was missing: instead of using the org.eclipse.ui.popupMenus-extension point, I had to use the org.eclipse.ui.menus-extension point with a menuContribution that has its locationURI-attribute pointing to popup:org.eclipse.ui.popup.any?after=additions. This menuContribution can include a command-element (achieving the goal of binding directly to an existing command), and this command-element´s visibleWhen-element can be bound to the activation status of the bound command's handler via the checkEnabled-attribute (achieving the goal of having the popup-menu entry visible only when the enablement for the command handler is satisfied).
What's bad is that the documentation of the org.eclipse.ui.menus-extension point states that the org.eclipse.ui.popupMenus-extension point is to be considered deprecated, but the documentation of org.eclipse.ui.popupMenus does not mention this fact.