{-# LANGUAGE DoRec #-} module Hbro.Keys ( -- * Other defaultKeyHandler, emacsKeyHandler, -- * Util stringify, keyToString, ) where -- {{{ Imports import Hbro.Core import Hbro.Types import Hbro.Util import Control.Monad hiding(forM_) --import Control.Monad.Trans --import Data.Foldable import Data.IORef import qualified Data.Map as M --import qualified Data.Set as S import Graphics.UI.Gtk.Abstract.Widget import Graphics.UI.Gtk.Gdk.EventM import Graphics.UI.Gtk.Gdk.Keys import Prelude hiding(mapM_) --import System.Console.CmdArgs (whenLoud) --import System.Glib.Signals -- }}} -- | Look for a callback associated to the given keystrokes and trigger it, if any. defaultKeyHandler :: KeysList -> String -> K (String, Bool) defaultKeyHandler keysList keystrokes = case M.lookup keystrokes (M.fromList keysList) of Just callback -> callback >> return (keystrokes, True) _ -> return (keystrokes, False) -- | Emacs-like key handler. emacsKeyHandler :: KeysList -- ^ Key bindings -> [String] -- ^ List of prefix keys -> String -> K (String, Bool) emacsKeyHandler keysList prefixes keystrokes = do keysRef <- getState "Hbro.Keys.manageSequentialKeys" "" io $ modifyIORef keysRef (++ keystrokes) chainedKeys <- io $ readIORef keysRef case elem chainedKeys prefixes of True -> do io $ modifyIORef keysRef (++ " ") return (chainedKeys ++ " ", False) _ -> do io $ writeIORef keysRef [] defaultKeyHandler keysList chainedKeys -- | Convert a KeyVal to a String. -- For printable characters, the corresponding String is returned, except for the space character for which "" is returned. -- For non-printable characters, the corresponding keyName wrapped into "< >" is returned. -- For modifiers, Nothing is returned. keyToString :: KeyVal -> Maybe String keyToString keyVal = case keyToChar keyVal of Just ' ' -> Just "" Just char -> Just [char] _ -> case keyName keyVal of "Caps_Lock" -> Nothing "Shift_L" -> Nothing "Shift_R" -> Nothing "Control_L" -> Nothing "Control_R" -> Nothing "Alt_L" -> Nothing "Alt_R" -> Nothing "Super_L" -> Nothing "Super_R" -> Nothing "Menu" -> Nothing "ISO_Level3_Shift" -> Nothing "dead_circumflex" -> Just "^" "dead_diaeresis" -> Just "ยจ" x -> Just ('<':x ++ ">") -- | Convert a Modifier to a String. stringify :: Modifier -> String stringify Control = "C-" --stringify' Shift = "S-" stringify Alt = "M-" stringify _ = [] -- | Convert key bindings list to a map. -- keysListToMap :: KeysList -> KeysMap -- keysListToMap = M.fromList . (map (\(a, b) -> ((S.fromList a, b), c)))