Skip to content

Commit

Permalink
Added leader-key like button
Browse files Browse the repository at this point in the history
  • Loading branch information
david-janssen committed Aug 4, 2020
1 parent bebf71d commit de85686
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 5 deletions.
27 changes: 27 additions & 0 deletions src/KMonad/Action.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ module KMonad.Action
-- $combs
, my
, matchMy
, after
, whenDone
, await
, awaitMy
, tHookF
Expand Down Expand Up @@ -162,6 +164,28 @@ tHookF :: MonadK m
-> m () -- ^ The resulting action
tHookF d a f = register $ Hook (Just $ Timeout d a) f


-- | Perform an action after a period of time has elapsed
--
-- This is essentially just a way to perform async actions using the KMonad hook
-- system.
after :: MonadK m
=> Milliseconds
-> m ()
-> m ()
after d a = do
let rehook t = after (d - t^.elapsed) a *> pure NoCatch
tHookF d a rehook

-- | Perform an action immediately after the current action is finished. NOTE:
-- there is no guarantee that another event doesn't outrace this, only that it
-- will happen as soon as the CPU gets to it.
whenDone :: MonadK m
=> m ()
-> m ()
whenDone = after 0


-- | Create a KeyPred that matches the Press or Release of the current button.
matchMy :: MonadK m => Switch -> m KeyPred
matchMy s = (==) <$> my s
Expand All @@ -176,6 +200,9 @@ await p a = hookF $ \e -> if p e
awaitMy :: MonadK m => Switch -> m Catch -> m ()
awaitMy s a = matchMy s >>= flip await (const a)




-- | Try to call a function on a succesful match of a predicate within a certain
-- time period. On a timeout, perform an action.
within :: MonadK m
Expand Down
6 changes: 6 additions & 0 deletions src/KMonad/Args/Joiner.hs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,12 @@ joinButton ns als =
KLayerSwitch t -> if t `elem` ns
then ret $ layerSwitch t
else throwError $ MissingLayer t
KLayerDelay s t -> if t `elem` ns
then ret $ layerDelay (fi s) t
else throwError $ MissingLayer t
KLayerNext t -> if t `elem` ns
then ret $ layerNext t
else throwError $ MissingLayer t

-- Various compound buttons
KComposeSeq bs -> view cmpKey >>= \c -> jst $ tapMacro . (c:) <$> mapM go bs
Expand Down
2 changes: 2 additions & 0 deletions src/KMonad/Args/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ buttonP = (lexeme . choice . map try $
, statement "tap-next" $ KTapNext <$> buttonP <*> buttonP
, statement "layer-toggle" $ KLayerToggle <$> word
, statement "layer-switch" $ KLayerSwitch <$> word
, statement "layer-delay" $ KLayerDelay <$> lexeme numP <*> word
, statement "layer-next" $ KLayerNext <$> word
, statement "around-next" $ KAroundNext <$> buttonP
, statement "tap-macro" $ KTapMacro <$> some buttonP
, KRef <$> derefP
Expand Down
6 changes: 6 additions & 0 deletions src/KMonad/Args/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ data DefButton
| KTapMacro [DefButton] -- ^ Sequence of buttons to tap
| KComposeSeq [DefButton] -- ^ Compose-key sequence
| KPause Milliseconds -- ^ Pause for a period of time
| KLayerDelay Int LayerTag -- ^ Switch to a layer for a period of time
| KLayerNext LayerTag -- ^ Perform next button in different layer
| KTrans -- ^ Transparent button that does nothing
| KBlock -- ^ Button that catches event
deriving Show
Expand Down Expand Up @@ -173,3 +175,7 @@ data KExpr
| KDefAlias DefAlias
deriving Show
makeClassyPrisms ''KExpr


--------------------------------------------------------------------------------
-- $act
15 changes: 11 additions & 4 deletions src/KMonad/Button.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ module KMonad.Button
-- * Button combinators
-- $combinators
, aroundNext
, layerDelay
, layerNext
, tapHold
, multiTap
, tapNext
Expand Down Expand Up @@ -201,10 +203,6 @@ tapHoldNext ms t h = onPress $ within ms (pure $ const True) (press h) $ \tr ->
then tap t *> pure Catch
else press h *> pure NoCatch





-- | Create a 'Button' that contains a number of delays and 'Button's. As long
-- as the next press is registered before the timeout, the multiTap descends
-- into its list. The moment a delay is exceeded or immediately upon reaching
Expand Down Expand Up @@ -236,4 +234,13 @@ multiTap l bs = onPress $ go bs
tapMacro :: [Button] -> Button
tapMacro bs = onPress $ mapM_ tap bs

-- | Switch to a layer for a period of time, then automatically switch back
layerDelay :: Milliseconds -> LayerTag -> Button
layerDelay d t = onPress $ do
layerOp (PushLayer t)
after d (layerOp $ PopLayer t)

layerNext :: LayerTag -> Button
layerNext t = onPress $ do
layerOp (PushLayer t)
await isPress (\_ -> whenDone (layerOp $ PopLayer t) *> pure NoCatch)
21 changes: 20 additions & 1 deletion template/atreus.kbd
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@

gm (layer-switch game)
col (layer-switch colemak)

;; Temporary switch

tmp (layer-delay 500 game-fun)
tm2 (layer-next symbols)
)


Expand All @@ -118,7 +123,7 @@

;; Numpad, punctuation, brackets
(deflayer numpad
+` ` ~ [ ] _ 7 8 9 /
+` ` ~ [ ] @tm2 7 8 9 /
+' " \_ \( \) _ 4 5 6 *
+~ ' | { } = 1 2 3 -
_ _ _ _ _ _ @fun _ 0 _ . +
Expand Down Expand Up @@ -177,3 +182,17 @@
F6 F7 F8 F9 F10 _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _
)


#| --------------------------------------------------------------------------

Template code that I wished parsed correctly

(defbutton
(on-press
(push-layer game-fun)
(after 500
(pop-layer game-fun)))
)

-------------------------------------------------------------------------- |#

0 comments on commit de85686

Please sign in to comment.