Skip to content

Commit

Permalink
Add command/handler which sends out arrow key presses when triggered
Browse files Browse the repository at this point in the history
We have had requests from people for easier ways to navigate the package
explorer, preferably using the HJKL keys like Vim does.

This commit adds a "Vrapper Up Arrow Map" command (and so on for the
other 3 arrows) to the General > Keys preference page which can be bound
to HJKL.

Do note that it should be bound to the "Vrapper Enabled on a View"
context to be safe; otherwise you would be unable to type HJKL in any
dialog or entry box.

As a safety measure the code will also fall back to just inserting the
bound keys if Vrapper is disabled or when the focused control is a
textbox. Other controls have not been tested because they're not
commonly available in Eclipse Views.

Fixes vrapper#173.
  • Loading branch information
albertdev committed Dec 20, 2018
1 parent 95e5b80 commit 25ec245
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 3 deletions.
71 changes: 69 additions & 2 deletions net.sourceforge.vrapper.eclipse/plugin.xml
Expand Up @@ -33,6 +33,30 @@
id="net.sourceforge.vrapper.eclipse.commands.vrapperShortcut"
name="Send to Vrapper"/>

<command
categoryId="net.sourceforge.vrapper.eclipse.commands"
description="Translates a given key into a press of the Up arrow"
id="net.sourceforge.vrapper.eclipse.commands.arrowMap.up"
name="Vrapper Up Arrow Map"/>

<command
categoryId="net.sourceforge.vrapper.eclipse.commands"
description="Translates a given key into a press of the Down arrow"
id="net.sourceforge.vrapper.eclipse.commands.arrowMap.down"
name="Vrapper Down Arrow Map"/>

<command
categoryId="net.sourceforge.vrapper.eclipse.commands"
description="Translates a given key into a press of the Left arrow"
id="net.sourceforge.vrapper.eclipse.commands.arrowMap.left"
name="Vrapper Left Arrow Map"/>

<command
categoryId="net.sourceforge.vrapper.eclipse.commands"
description="Translates a given key into a press of the Right arrow"
id="net.sourceforge.vrapper.eclipse.commands.arrowMap.right"
name="Vrapper Right Arrow Map"/>

</extension>


Expand Down Expand Up @@ -171,7 +195,14 @@

<!-- Re-usable activation expressions. -->
<extension point="org.eclipse.core.expressions.definitions">
<!-- Evaluates to true when Vrapper is active and a Vrapper instance is focused -->
<!-- Evaluates to true when Vrapper is enabled -->
<definition id="net.sourceforge.vrapper.expr.enabled">
<!-- Check that Vrapper is enabled -->
<with variable="net.sourceforge.vrapper.source.enabled">
<equals value="true"/>
</with>
</definition>
<!-- Evaluates to true when Vrapper is enabled and a Vrapper instance is focused -->
<definition id="net.sourceforge.vrapper.expr.activeanymode">
<and>
<!-- Check that we're even on an editor -->
Expand All @@ -190,7 +221,7 @@
</not>
</and>
</definition>
<!-- Evaluates to true when Vrapper is active, a Vrapper instance is focused and command line is open. -->
<!-- Evaluates to true when Vrapper is enabled, a Vrapper instance is focused and command line is open. -->
<definition id="net.sourceforge.vrapper.expr.commandlinemode">
<and>
<!-- Check that we're even on an editor -->
Expand Down Expand Up @@ -224,6 +255,36 @@
</activeWhen>
</handler>

<!-- Remaps H/J/K/L (or whatever is bound) to Left/Down/Up/Right keypresses which views understand. -->
<handler
class="net.sourceforge.vrapper.eclipse.actions.VrapperArrowMapHandler"
commandId="net.sourceforge.vrapper.eclipse.commands.arrowMap.up">
<activeWhen>
<reference definitionId="net.sourceforge.vrapper.expr.enabled"/>
</activeWhen>
</handler>
<handler
class="net.sourceforge.vrapper.eclipse.actions.VrapperArrowMapHandler"
commandId="net.sourceforge.vrapper.eclipse.commands.arrowMap.down">
<activeWhen>
<reference definitionId="net.sourceforge.vrapper.expr.enabled"/>
</activeWhen>
</handler>
<handler
class="net.sourceforge.vrapper.eclipse.actions.VrapperArrowMapHandler"
commandId="net.sourceforge.vrapper.eclipse.commands.arrowMap.left">
<activeWhen>
<reference definitionId="net.sourceforge.vrapper.expr.enabled"/>
</activeWhen>
</handler>
<handler
class="net.sourceforge.vrapper.eclipse.actions.VrapperArrowMapHandler"
commandId="net.sourceforge.vrapper.eclipse.commands.arrowMap.right">
<activeWhen>
<reference definitionId="net.sourceforge.vrapper.expr.enabled"/>
</activeWhen>
</handler>

<!-- Override default HOME / END / Ctrl + Arrow / Past / ... commands in command line. -->
<handler
class="net.sourceforge.vrapper.eclipse.actions.VrapperCommandLineMotionHandler"
Expand Down Expand Up @@ -311,6 +372,12 @@
</context>

<!-- Vrapper contexts proper -->
<context
description="Shortcuts are used when Vrapper is enabled but not focused (e.g. on a view)"
id="net.sourceforge.vrapper.eclipse.enabledOnView"
name="Vrapper Enabled on a View"
parentId="net.sourceforge.vrapper.eclipse.dummy5">
</context>
<context
description="Shortcuts are used when Vrapper is focused and enabled"
id="net.sourceforge.vrapper.eclipse.active"
Expand Down
@@ -0,0 +1,76 @@
package net.sourceforge.vrapper.eclipse.actions;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;

import net.sourceforge.vrapper.log.VrapperLog;

/**
* Remaps an kind of key into the press of an Up / Down / Left / Right arrow key.
*/
public class VrapperArrowMapHandler extends AbstractHandler {

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
String commandId = event.getCommand().getId();

if ( ! (event.getTrigger() instanceof Event)) {
return null;
}
Event triggerEvent = (Event) event.getTrigger();
if (triggerEvent.type != SWT.KeyDown) {
VrapperLog.debug("Shortcut handler received an activation other than key type?!?");
return null;
}

Widget widget = triggerEvent.widget;

// Act as if we're in Insert mode if textbox is focused: insert input key in widget
if (widget instanceof Text || widget instanceof StyledText) {
// Check that this command is bound to a Unicode character (and not F1 or something)
if ((triggerEvent.stateMask & SWT.MODIFIER_MASK) == 0
&& (triggerEvent.keyCode & SWT.KEYCODE_BIT) == 0) {

String input = new StringBuilder().appendCodePoint(triggerEvent.keyCode).toString();
if (widget instanceof Text) {
Text textBox = (Text) widget;
textBox.insert(input);
} else if (widget instanceof StyledText) {
StyledText styledText = (StyledText) widget;
styledText.insert(input);
}
}
} else {

Event mappedEvent = null;
// This handler can accept 4 commands (up/down/left/right) and translates them into arrow key presses
if (commandId.endsWith(".up")) {
mappedEvent = keyEvent(SWT.ARROW_UP);
} else if (commandId.endsWith(".down")) {
mappedEvent = keyEvent(SWT.ARROW_DOWN);
} else if (commandId.endsWith(".right")) {
mappedEvent = keyEvent(SWT.ARROW_RIGHT);
} else if (commandId.endsWith(".left")) {
mappedEvent = keyEvent(SWT.ARROW_LEFT);
}
if (mappedEvent != null) {
triggerEvent.display.post(mappedEvent);
}
}

return null;
}

private static Event keyEvent(int keyCode) {
Event result = new Event();
result.type = SWT.KeyDown;
result.keyCode = keyCode;
return result;
}
}
Expand Up @@ -17,6 +17,7 @@
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchListener;
Expand Down Expand Up @@ -179,14 +180,34 @@ public boolean preShutdown(IWorkbench arg0, boolean arg1) {

void activateVrapperShortcutContexts() {
final IContextService contextService = (IContextService) getWorkbench().getService(IContextService.class);


contextService.activateContext("net.sourceforge.vrapper.eclipse.enabledOnView", vrapperEnabledOnViewExpression(), true);

contextService.activateContext("net.sourceforge.vrapper.eclipse.active", vrapperEnabledInAnyModeExpression(), true);
contextService.activateContext("net.sourceforge.vrapper.eclipse.active.normal", vrapperEnabledInModeExpression(NormalMode.NAME), true);
contextService.activateContext("net.sourceforge.vrapper.eclipse.active.command", vrapperEnabledInModeExpression(CommandLineMode.NAME), true);
contextService.activateContext("net.sourceforge.vrapper.eclipse.active.visual", vrapperEnabledInModeExpression(VisualMode.NAME), true);
contextService.activateContext("net.sourceforge.vrapper.eclipse.active.insert", vrapperEnabledInModeExpression(InsertMode.NAME), true);
}

private static Expression vrapperEnabledOnViewExpression() {
return new Expression() {
@Override
public EvaluationResult evaluate(IEvaluationContext context) throws CoreException {
Object currentlyActivePart = context.getVariable(ISources.ACTIVE_PART_NAME);
boolean onAView = currentlyActivePart instanceof IViewPart;
boolean vrapperEnabled = (Boolean) context.getVariable(VrapperStatusSourceProvider.SOURCE_ENABLED);
return EvaluationResult.valueOf(vrapperEnabled && onAView);
}

@Override
public void collectExpressionInfo(ExpressionInfo info) {
info.addVariableNameAccess(ISources.ACTIVE_PART_NAME);
info.addVariableNameAccess(VrapperStatusSourceProvider.SOURCE_ENABLED);
}
};
}

private static Expression vrapperEnabledInAnyModeExpression() {
return new Expression() {
@Override
Expand Down

0 comments on commit 25ec245

Please sign in to comment.