aboutsummaryrefslogtreecommitdiff
path: root/lib/Daffm/Event.hs
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-10-04 18:07:30 +0530
committerAkshay Nair <phenax5@gmail.com>2025-10-04 19:10:06 +0530
commita302dfc2aabda53446fb38e035e61ae91b28f84a (patch)
tree67ca03f33ebf31e198ac5a883100b96cc387f264 /lib/Daffm/Event.hs
parentb05be850349dbb813d2af6f3ee7a2fc3bf98b8ef (diff)
downloaddaffm-a302dfc2aabda53446fb38e035e61ae91b28f84a.tar.gz
daffm-a302dfc2aabda53446fb38e035e61ae91b28f84a.zip
Add multi-key handling + command parsing + shell/shell! aliases
Diffstat (limited to 'lib/Daffm/Event.hs')
-rw-r--r--lib/Daffm/Event.hs68
1 files changed, 47 insertions, 21 deletions
diff --git a/lib/Daffm/Event.hs b/lib/Daffm/Event.hs
index 247719b..262686b 100644
--- a/lib/Daffm/Event.hs
+++ b/lib/Daffm/Event.hs
@@ -1,42 +1,68 @@
module Daffm.Event where
-import qualified Brick.Main as M
import qualified Brick.Types as T
import qualified Brick.Widgets.Edit as Editor
import qualified Brick.Widgets.List as L
-import Control.Monad.State (gets, modify)
+import Control.Monad.State (get, gets, modify)
import Daffm.Action.Cmdline
-import Daffm.Action.Core
+import Daffm.Action.Commands
import Daffm.State (cacheDirPosition)
-import Daffm.Types (AppEvent, AppState (..), FocusTarget (..))
+import Daffm.Types (AppEvent, AppState (..), Command (..), FocusTarget (..), Key, KeyMatchResult (..), KeySequence, Keymap)
+import qualified Data.Map as Map
+import Data.Maybe (fromMaybe)
import qualified Graphics.Vty as V
appEvent :: T.BrickEvent FocusTarget e -> AppEvent ()
appEvent brickevent@(T.VtyEvent event) = do
focusTarget <- gets stateFocusTarget
case (focusTarget, event) of
- (FocusMain, V.EvKey (V.KChar 'l') []) -> openSelectedFile
- (FocusMain, V.EvKey (V.KChar 'h') []) -> goBackToParentDir
- (FocusMain, V.EvKey V.KEnter []) -> openSelectedFile
- (FocusMain, V.EvKey V.KBS []) -> goBackToParentDir
- (FocusMain, V.EvKey (V.KChar '~') []) -> goHome
- (FocusMain, V.EvKey (V.KChar ':') []) -> enterCmdline
- (FocusMain, V.EvKey (V.KChar '!') []) -> setCmdlineText "!" >> enterCmdline
- (FocusMain, V.EvKey (V.KChar 'q') []) -> M.halt
- (FocusMain, V.EvKey (V.KChar 'r') [V.MCtrl]) -> reloadDir
- (FocusMain, V.EvKey (V.KChar 'v') []) -> toggleCurrentFileSelection
- (FocusMain, V.EvKey (V.KChar 'C') []) -> clearFileSelections
- -- Just for testing
- (FocusMain, V.EvKey (V.KChar 'p') [V.MCtrl]) -> evaluateCommand "!!chafa -f kitty %"
(FocusCmdline, V.EvKey V.KEsc []) -> leaveCmdline
(FocusCmdline, V.EvKey V.KEnter []) -> runCmdline
- (FocusMain, _) -> do
- files <- gets stateFiles
- newFiles <- T.nestEventM' files (L.handleListEventVi L.handleListEvent event)
- modify (\appState -> appState {stateFiles = newFiles})
(FocusCmdline, _) -> do
editor <- gets stateCmdlineEditor
newEditor <- T.nestEventM' editor (Editor.handleEditorEvent brickevent)
modify (\appState -> appState {stateCmdlineEditor = newEditor})
+ (FocusMain, V.EvKey key []) -> do
+ appendToKeySequence key
+ processKeySequence >>= \case
+ MatchFailure -> do
+ files <- gets stateFiles
+ newFiles <- T.nestEventM' files (L.handleListEventVi L.handleListEvent event)
+ modify (\appState -> appState {stateFiles = newFiles})
+ _ -> pure ()
+ (FocusMain, _) -> do
+ files <- gets stateFiles
+ newFiles <- T.nestEventM' files (L.handleListEventVi L.handleListEvent event)
+ modify (\appState -> appState {stateFiles = newFiles})
modify cacheDirPosition
appEvent _ = pure ()
+
+matchKeySequence :: Keymap -> KeySequence -> KeyMatchResult
+matchKeySequence keymaps keys
+ | Map.member keys keymaps =
+ MatchSuccess . fromMaybe CmdNoop $ Map.lookup keys keymaps
+ | otherwise = partial keymaps keys
+ where
+ partial _ [] = MatchFailure
+ partial (Map.null -> True) _ = MatchFailure
+ partial keymaps' keys' = if hasMatch then MatchPartial else MatchFailure
+ where
+ hasMatch = any (startsWith keys' . fst) (Map.toList keymaps')
+ startsWith ls1 ls2 = ls1 == take (length ls1) ls2
+
+processKeySequence :: AppEvent KeyMatchResult
+processKeySequence = do
+ (AppState {stateKeyMap, stateKeySequence}) <- get
+ let match = matchKeySequence stateKeyMap stateKeySequence
+ case match of
+ MatchSuccess cmd -> do
+ processCommand cmd
+ modify (\st -> st {stateKeySequence = []})
+ MatchPartial -> pure ()
+ MatchFailure -> do
+ modify (\st -> st {stateKeySequence = []})
+ pure match
+
+appendToKeySequence :: Key -> AppEvent ()
+appendToKeySequence key =
+ modify (\st -> st {stateKeySequence = stateKeySequence st <> [key]})