Karya, built on Sun Nov 26 01:04:37 PST 2017 (patch 0a920b2bde70c0cbac8ee09d158064798b61bbe5)

Safe HaskellNone




Support for efficient keymaps.

The sequece of Cmds which return Continue or Done is flexible, but probably inefficient in the presence of hundreds of commands. In addition, it can't warn about Cmds that respond to overlapping Msgs, e.g. respond to the same key.

Keymaps provide an efficient way to respond to a useful subset of Msgs, i.e. those which are considered 'key down' type msgs. The exact definition is in Bindable.

Keys are bound using SimpleMods, which are higher level than the ones in Ui.Key. This provides allows some abstraction between they key bindings and which actual modifiers those imply, and allows the conflation of multiple modifiers.

If you bind to a shifted key, it will be converted to Shift + unshifted by KeyLayouts.to_unshifted. But if you want to bind to the same physical key with and without shift, then you should bind to the unshifted version and add Shift yourself.



plain_key :: Cmd.M m => Key.Key -> Text -> m () -> [Binding m] Source #

Bind a Key with no modifiers.

plain_char :: Cmd.M m => Char -> Text -> m () -> [Binding m] Source #

Bind a Char with no modifiers.

shift_char :: Cmd.M m => Char -> Text -> m () -> [Binding m] Source #

command_char :: Cmd.M m => Char -> Text -> m () -> [Binding m] Source #

Bind a Char with the PrimaryCommand.

secondary_char :: Cmd.M m => Char -> Text -> m () -> [Binding m] Source #

Bind a Char with the SecondaryCommand.

bind_key :: Cmd.M m => [SimpleMod] -> Key.Key -> Text -> m () -> [Binding m] Source #

Bind a key with the given modifiers.

bind_key_status :: [SimpleMod] -> Key.Key -> Text -> m Cmd.Status -> [Binding m] Source #

Bind a key with a Cmd that returns Status.

bind_repeatable :: Cmd.M m => [SimpleMod] -> Key.Key -> Text -> m () -> [Binding m] Source #

Like bind_key, but the binding will be retriggered on key repeat.

bind_click :: Cmd.M m => [SimpleMod] -> Types.MouseButton -> MouseOn -> Int -> Text -> (Msg.Msg -> m ()) -> [Binding m] Source #

bind_click passes the Msg to the cmd, since mouse cmds are more likely to want the msg to find out where the click was. clicks is 1 for a single click, 2 for a double click, etc.

bind_drag :: Cmd.M m => [SimpleMod] -> Types.MouseButton -> MouseOn -> Text -> (Msg.Msg -> m ()) -> [Binding m] Source #

A bind_drag binds both the click and the drag. It's conceivable to have click and drag bound to different commands, but I don't have any yet.

bind :: Cmd.M m => [SimpleMod] -> Bindable -> Text -> (Msg.Msg -> m ()) -> [Binding m] Source #

Like bind_status but the Cmd is expected to return (), which will become Cmd.Done. Since the cmd has already been matched on the bound key this is likely what it would have done anyway.

bind_status :: [SimpleMod] -> Bindable -> Text -> (Msg.Msg -> m Cmd.Status) -> [Binding m] Source #

This is the most general Binding constructor: bind any Bindable with any modifiers, and don't assume the cmd returns Done.

A capital letter is shorthand for Shift + Char.toLower c.


expand_bindable :: Bindable -> [Bindable] Source #

A binding that accepts a KeyRepeat should also accept a KeyDown.


make_cmd_map :: [Binding m] -> (CmdMap m, [Text]) Source #

Create a CmdMap for efficient lookup and return warnings encountered during construction.

make_cmd :: Cmd.M m => CmdMap m -> Msg.Msg -> m Cmd.Status Source #

Create a cmd that dispatches into the given CmdMap.

To look up a cmd, the Msg is restricted to a Bindable. Then modifiers that are allowed to overlap (such as keys) are stripped out of the mods and the KeySpec is looked up in the keymap.

data SimpleMod Source #

The Msg contains the low level key information, but most commands should probably use these higher level modifiers. That way left and right shifts work the same, and cmds can use Command as customary on the Mac and Control as customary on linux.



Primary command key: command on Mac, control on Linux and Windows. This should be used for core and global commands.


Secondary comamnd key: control or option on Mac, alt on Linux and Windows. I'm not sure what this should be used for, but perhaps it can be for more specific event text modifications, while PrimaryCommand is for general purpose modifications. Also, it should have non-primitive cmds, so if you override them locally you won't lose anything essential.

Mouse Types.MouseButton

Having mouse here allows for mouse button chording.

really_control :: SimpleMod Source #

Sometimes you really want to bind to control, regardless of the platform.


simple_mod_map :: [(SimpleMod, [Key.Modifier])] Source #

Map a SimpleMod to the Key.Modifiers it implies.


data CmdSpec m Source #

Pair a Cmd with a descriptive string that can be used for logging, undo, etc.


CmdSpec Text (Msg.Msg -> m Cmd.Status) 

cspec_ :: Text -> m Cmd.Status -> CmdSpec m Source #

Make a CmdSpec for a CmdM, i.e. a Cmd that doesn't take a Msg.


overlaps :: [Binding m] -> [[Text]] Source #

mods_down :: Cmd.M m => m (Set Cmd.Modifier) Source #

Return the mods currently down, stripping out non-modifier keys and notes, so that overlapping keys will still match. Mouse mods are not filtered, so each mouse chord can be bound individually.

data Bindable Source #


Key Bool Key.Key

Key IsRepeat Key

Click Types.MouseButton MouseOn Int

Click MouseButton Clicks

Drag Types.MouseButton MouseOn 
Release Types.MouseButton MouseOn

Mouse button release.

Note Midi.Channel Midi.Key

Channel can be used to restrict bindings to a certain keyboard. This should probably be something more abstract though, such as a device which can be set by the static config.

pretty printing

key layout

physical_key :: CallStack.Stack => Char -> Char Source #

Map a physical key, written relative to USA qwerty layout, to whatever character that key actually emits (if the layout is already USA qwerty then it's id of course). This is for layouts which should be done based on physical key position, like piano-style keyboards. It makes the overlapping-ness of non-mapped keys hard to predict though.

Since it's intended to map literal key characters, there is no accomodation for failure. Really this should be done at compile time, so it's conceptually a compile time error.

TODO isn't there some way I can get this at compile time? template haskell?