Skip to content

Commit

Permalink
feat(keybindings): execute keybinding starting with : as ex command (#…
Browse files Browse the repository at this point in the history
…2397)

A simple change that allows keybindings to invoke ex commands directly, and could address quite a few of the requests in #1423. The downside of doing this instead of implementing proper commands is of course that they won't be discoverable through the command palette, but this doesn't prevent proper commands to be added either, so I think it might be a nice convenient stop-gap solution to unblock people at least.

Example:

```
  {key: "kk", command: ":split", when: "editorTextFocus"}
```

Let me know if you think this is a viable approach @bryphe, then I'll add a few integration tests before it's merged.

Fixes #807
  • Loading branch information
glennsl authored Sep 7, 2020
1 parent f698991 commit e051efd
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 7 deletions.
49 changes: 49 additions & 0 deletions integration_test/ExCommandKeybindingTest.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
open Oni_Model;
open Oni_IntegrationTestLib;
open Actions;

let keybindings =
Some(
{|
[
{"key": "kk", "command": ":split", "when": "editorTextFocus"}
]
|},
);

runTest(
~keybindings,
~name="ExCommandKeybindingTest",
(dispatch, wait, _) => {
let input = key => {
let keyPress =
EditorInput.KeyPress.{
scancode: Sdl2.Scancode.ofName(key),
keycode: Sdl2.Keycode.ofName(key),
modifiers: EditorInput.Modifiers.none,
};
let time = Revery.Time.now();

dispatch(KeyDown(keyPress, time));
//dispatch(TextInput(key));
dispatch(KeyUp(keyPress, time));
};

wait(~name="Initial sanity check", (state: State.t) => {
let splitCount =
state.layout |> Feature_Layout.visibleEditors |> List.length;

splitCount == 1;
});

input("k");
input("k");

wait(~name="Wait for split to be created", (state: State.t) => {
let splitCount =
state.layout |> Feature_Layout.visibleEditors |> List.length;

splitCount == 2;
});
},
);
61 changes: 61 additions & 0 deletions integration_test/ExCommandKeybindingWithArgsTest.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
open Oni_Core;
open Oni_Model;
open Oni_IntegrationTestLib;
open Actions;

let keybindings =
Some(
{|
[
{"key": "kk", "command": ":d 2", "when": "editorTextFocus"}
]
|},
);

runTest(
~keybindings,
~name="ExCommandKeybindingTest",
(dispatch, wait, _) => {
let input = key => {
let keyPress =
EditorInput.KeyPress.{
scancode: Sdl2.Scancode.ofName(key),
keycode: Sdl2.Keycode.ofName(key),
modifiers: EditorInput.Modifiers.none,
};
let time = Revery.Time.now();

dispatch(KeyDown(keyPress, time));
//dispatch(TextInput(key));
dispatch(KeyUp(keyPress, time));
};

let testFile = getAssetPath("some-test-file.txt");
dispatch(Actions.OpenFileByPath(testFile, None, None));

wait(~name="Verify buffer is loaded", (state: State.t) =>
switch (Selectors.getActiveBuffer(state)) {
| Some(buffer) =>
Buffer.getShortFriendlyName(buffer) == Some("some-test-file.txt")
| None => false
}
);

wait(~name="Verify initial line count", (state: State.t) =>
switch (Selectors.getActiveBuffer(state)) {
| Some(buffer) => Buffer.getNumberOfLines(buffer) == 3
| None => false
}
);

input("k");
input("k");

wait(~name="Wait for split to be created", (state: State.t) =>
switch (Selectors.getActiveBuffer(state)) {
| Some(buffer) => Buffer.getNumberOfLines(buffer) == 1
| None => false
}
);
},
);
4 changes: 4 additions & 0 deletions integration_test/dune
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
EditorFontFromPathTest
EditorFontValidTest
EditorUtf8Test
ExCommandKeybindingTest
ExCommandKeybindingWithArgsTest
ExtConfigurationChangedTest
ExtHostBufferOpenTest
ExtHostBufferUpdatesTest
Expand Down Expand Up @@ -77,6 +79,8 @@
EditorFontFromPathTest.exe
EditorFontValidTest.exe
EditorUtf8Test.exe
ExCommandKeybindingTest.exe
ExCommandKeybindingWithArgsTest.exe
ExtConfigurationChangedTest.exe
ExtHostBufferOpenTest.exe
ExtHostBufferUpdatesTest.exe
Expand Down
26 changes: 19 additions & 7 deletions src/Store/KeyBindingsStoreConnector.re
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,11 @@ let start = maybeKeyBindingsFilePath => {
}
);

let executeExCommandEffect = command =>
Isolinear.Effect.create(~name="keybindings.executeExCommand", () =>
ignore(Vim.command(command): Vim.Context.t)
);

let updater = (state: State.t, action: Actions.t) => {
switch (action) {
| Actions.Init => (state, loadKeyBindingsEffect(true))
Expand All @@ -545,14 +550,21 @@ let start = maybeKeyBindingsFilePath => {
)

| KeybindingInvoked({command}) =>
switch (Command.Lookup.get(command, State.commands(state))) {
| Some((command: Command.t(_))) => (
if (command |> Utility.StringEx.startsWith(~prefix=":")) {
(
state,
executeCommandEffect(command.msg),
)
| None =>
Log.errorf(m => m("Unknown command: %s", command));
(state, Isolinear.Effect.none);
executeExCommandEffect(Base.String.drop_prefix(command, 1)),
);
} else {
switch (Command.Lookup.get(command, State.commands(state))) {
| Some((command: Command.t(_))) => (
state,
executeCommandEffect(command.msg),
)
| None =>
Log.errorf(m => m("Unknown command: %s", command));
(state, Isolinear.Effect.none);
};
}

| _ => (state, Isolinear.Effect.none)
Expand Down

0 comments on commit e051efd

Please sign in to comment.