Skip to content

Commit

Permalink
Bugfix/Menu Input events (onivim#183)
Browse files Browse the repository at this point in the history
Use Window listener rather than Reglfw listener to handle the `keypress` input, this allows the input component to get `backspace`, `arrow` key events etc.

This adds the ability to use `C-N` and `C-P` whilst the input is in focus as well as using `ESC`.
  • Loading branch information
akinsho authored Mar 27, 2019
1 parent ecdda98 commit 5d55e42
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 94 deletions.
12 changes: 6 additions & 6 deletions assets/configuration/keybindings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"bindings": [
{ "key": "<C-P>", "command": "quickOpen.open", "when": ["editorTextFocus"] },
{ "key": "<S-C-P>", "command": "commandPalette.open", "when": ["editorTextFocus"] },
{ "key": "<ESC>", "command": "menu.close", "when": ["menuFocus"] },
{ "key": "<C-N>", "command": "menu.next", "when": ["menuFocus"] },
{ "key": "<C-P>", "command": "menu.previous", "when": ["menuFocus"] },
{ "key": "<CR>", "command": "menu.select", "when": ["menuFocus"] }
{ "key": "<C-P>", "command": "quickOpen.open", "when": [["editorTextFocus"]] },
{ "key": "<S-C-P>", "command": "commandPalette.open", "when": [["editorTextFocus"]] },
{ "key": "<ESC>", "command": "menu.close", "when": [["menuFocus"]] },
{ "key": "<C-N>", "command": "menu.next", "when": [["menuFocus"], ["textInputFocus"]] },
{ "key": "<C-P>", "command": "menu.previous", "when": [["menuFocus"], ["textInputFocus"]] },
{ "key": "<CR>", "command": "menu.select", "when": [["menuFocus"], ["textInputFocus"]] }
]
}
8 changes: 4 additions & 4 deletions src/editor/Core/Keybindings.re
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
open Types.Input;

[@deriving (show, yojson({strict: false, exn: false}))]
[@deriving (show({with_path: false}), yojson({strict: false, exn: false}))]
type keyBindings = {
key: string,
command: string,
[@key "when"]
condition: controlMode,
condition: list(controlMode),
};

[@deriving (show, yojson({strict: false, exn: false}))]
[@deriving (show({with_path: false}), yojson({strict: false, exn: false}))]
type t = list(keyBindings);

[@deriving (show, yojson({strict: false, exn: false}))]
[@deriving (show({with_path: false}), yojson({strict: false, exn: false}))]
type json_keybindings = {bindings: t};

let ofFile = filePath =>
Expand Down
41 changes: 22 additions & 19 deletions src/editor/Core/Types.re
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Index = {
[@deriving show]
[@deriving show({with_path: false})]
type t =
| ZeroBasedIndex(int)
| OneBasedIndex(int);
Expand All @@ -18,7 +18,7 @@ module Index = {
};

module EditorSize = {
[@deriving show]
[@deriving show({with_path: false})]
type t = {
pixelWidth: int,
pixelHeight: int,
Expand Down Expand Up @@ -59,7 +59,7 @@ module Mode = {
* A buffer: represents a file
*/
module Views = {
[@deriving show]
[@deriving show({with_path: false})]
type t =
| Window
| Tab
Expand All @@ -69,7 +69,7 @@ module Views = {
| Buffer
| Tab;

[@deriving show]
[@deriving show({with_path: false})]
type viewOperation =
(~path: string=?, ~id: int=?, ~openMethod: openMethod=?, unit) => unit;
};
Expand All @@ -79,7 +79,7 @@ type openMethod =
| Buffer;

module BufferPosition = {
[@deriving show]
[@deriving show({with_path: false})]
type t = {
line: Index.t,
character: Index.t,
Expand All @@ -93,7 +93,7 @@ module BufferPosition = {
};
};

[@deriving show]
[@deriving show({with_path: false})]
type buftype =
| Empty
| Help
Expand All @@ -117,7 +117,7 @@ let getBufType = bt =>
};

module BufferMetadata = {
[@deriving show]
[@deriving show({with_path: false})]
type t = {
filePath: option(string),
fileType: option(string),
Expand Down Expand Up @@ -150,15 +150,15 @@ module BufferMetadata = {
};

module BufferNotification = {
[@deriving show]
[@deriving show({with_path: false})]
type t = {
bufferId: int,
buffers: list(BufferMetadata.t),
};
};

module BufferUpdate = {
[@deriving (show, yojson({strict: false, exn: true}))]
[@deriving (show({with_path: false}), yojson({strict: false, exn: true}))]
type t = {
id: int,
startLine: int,
Expand All @@ -177,13 +177,13 @@ module BufferUpdate = {
};

module Tabline = {
[@deriving show]
[@deriving show({with_path: false})]
type t = {
tab: int,
name: string,
};

[@deriving show]
[@deriving show({with_path: false})]
type tabs = list(t);
};

Expand Down Expand Up @@ -219,14 +219,14 @@ module UiFont = {
let create = (~fontFile, ~fontSize, ()) => {fontFile, fontSize};
};

[@deriving show]
[@deriving show({with_path: false})]
type wildmenu = {
items: list(string),
show: bool,
selected: int,
};

[@deriving show]
[@deriving show({with_path: false})]
type commandline = {
content: string,
firstC: string,
Expand All @@ -238,34 +238,37 @@ type commandline = {
};

module Input = {
[@deriving (show, yojson({strict: false, exn: false}))]
[@deriving
(show({with_path: false}), yojson({strict: false, exn: false}))
]
type controlMode =
| [@name "menuFocus"] MenuFocus
| [@name "textInputFocus"] TextInputFocus
| [@name "editorTextFocus"] EditorTextFocus;

[@deriving show]
[@deriving show({with_path: false})]
type keyBindings = {
key: string,
command: string,
};
};

module Effects = {
[@deriving show]
[@deriving show({with_path: false})]
type t = {
openFile: Views.viewOperation,
getCurrentDir: unit => option(string),
};
};

module UiMenu = {
[@deriving show]
[@deriving show({with_path: false})]
type menu =
| QuickOpen
| CommandPalette
| Closed;

[@deriving show]
[@deriving show({with_path: false})]
type command = {
name: string,
command: unit => unit,
Expand All @@ -274,7 +277,7 @@ module UiMenu = {

type commandFactory = Effects.t => list(command);

[@deriving show]
[@deriving show({with_path: false})]
type t = {
effects: option(Effects.t),
searchQuery: string,
Expand Down
10 changes: 10 additions & 0 deletions src/editor/Model/Commands.re
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ let oniCommands = [
command: _ => [
MenuOpen((CommandPalette, CommandPalette.commands)),
SetInputControlMode(MenuFocus),
SetInputControlMode(TextInputFocus),
],
},
{
name: "quickOpen.open",
command: _ => [
MenuOpen((QuickOpen, QuickOpen.content)),
SetInputControlMode(MenuFocus),
SetInputControlMode(TextInputFocus),
],
},
{
Expand All @@ -26,6 +28,14 @@ let oniCommands = [
},
{name: "menu.next", command: _ => [MenuPosition(1)]},
{name: "menu.previous", command: _ => [MenuPosition(-1)]},
{
name: "menu.next",
command: _ => [SetInputControlMode(MenuFocus), MenuPosition(1)],
},
{
name: "menu.previous",
command: _ => [SetInputControlMode(MenuFocus), MenuPosition(-1)],
},
{
name: "menu.select",
command: _ => [MenuSelect, SetInputControlMode(EditorTextFocus)],
Expand Down
38 changes: 32 additions & 6 deletions src/editor/UI/MenuView.re
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,27 @@ let getIcon = icon =>
| None => ""
};

let handleChange = ({value, _}: Input.changeEvent) =>
GlobalContext.current().dispatch(MenuSearch(value));
let handleChange = (event: Input.changeEvent) =>
GlobalContext.current().dispatch(MenuSearch(event.value));

let handleKeyDown = (event: NodeEvents.keyEventParams) =>
switch (event) {
| {key: Revery.Key.KEY_ESCAPE, _} =>
GlobalContext.current().dispatch(SetInputControlMode(MenuFocus))
| _ => ()
};

let loseFocusOnClose = isOpen =>
/**
TODO: revery-ui/revery#412 if the menu is hidden abruptly the element is not automatically unfocused
as revery is unaware the element is no longer in focus
*/
(
switch (Focus.focused, isOpen) {
| ({contents: Some(_)}, false) => Focus.loseFocus()
| (_, _) => ()
}
);

let createElement =
(
Expand All @@ -51,8 +70,14 @@ let createElement =
~theme: Theme.t,
(),
) =>
component(hooks =>
(
component(hooks => {
let hooks =
React.Hooks.effect(
Always,
() => Some(() => loseFocusOnClose(menu.isOpen)),
hooks,
);
React.(
hooks,
menu.isOpen
? <View style={containerStyles(theme)}>
Expand All @@ -63,6 +88,7 @@ let createElement =
cursorColor=Colors.white
style={inputStyles(font.fontFile)}
onChange=handleChange
onKeyDown=handleKeyDown
/>
</View>
<ScrollView style=Style.[height(menuHeight - 50)]>
Expand All @@ -80,5 +106,5 @@ let createElement =
</ScrollView>
</View>
: React.listToElement([]),
)
);
);
});
Loading

0 comments on commit 5d55e42

Please sign in to comment.