1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Use for_" #-}
module Daffm.Action.Commands where
import qualified Brick as M
import Control.Monad (forM_)
import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad.State (modify)
import Daffm.Action.Cmdline
import Daffm.Action.Core
import Daffm.Keymap (parseKeySequence)
import Daffm.Types
import Daffm.Utils (trim, trimStart)
import Data.Bifunctor (Bifunctor (second))
import Data.Char (isSpace)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import qualified Data.Text as Text
import qualified Data.Text.IO as Text
import qualified System.Process as Proc
runCmdline :: AppEvent ()
runCmdline = do
cmd <- getCmdlineText
leaveCmdline
evaluateCommand cmd
parseCommand :: Text.Text -> Maybe Command
parseCommand (Text.splitAt 2 -> ("!!", cmd)) = Just $ CmdShell True cmd
parseCommand (Text.splitAt 1 -> ("!", cmd)) = Just $ CmdShell False cmd
parseCommand cmd = mkCmd . splitCmdArgs $ trimStart cmd
where
splitCmdArgs = second trimStart . Text.break isSpace
mkCmd = \case
("q", _) -> Just CmdQuit
("quit", _) -> Just CmdQuit
("shell!", cmd') -> Just $ CmdShell True cmd'
("shell", cmd') -> Just $ CmdShell False cmd'
("command-shell", cmd') -> Just $ CmdCommandShell cmd'
("back", _) -> Just CmdGoBack
("open", _) -> Just CmdOpenSelection
("reload", _) -> Just CmdReload
("cd", dir) -> Just $ CmdChangeDir dir
("noop", _) -> Just CmdNoop
("cmdline-enter", _) -> Just CmdEnterCmdline
("cmdline-leave", _) -> Just CmdLeaveCmdline
("cmdline-set", txt) -> Just $ CmdSetCmdline txt
("selection-toggle", _) -> Just CmdToggleSelection
("selection-clear", _) -> Just CmdClearSelection
("search", term) -> Just $ CmdSearch $ trim term
("search-next", _) -> Just $ CmdSearchNext 1
("search-prev", _) -> Just $ CmdSearchNext (-1)
("map", Text.break isSpace -> (keysraw, cmdraw)) -> do
keys <- parseKeySequence keysraw
cmd' <- parseCommand $ trimStart cmdraw
pure $ CmdKeymapSet keys cmd'
_ -> Nothing
readCommandLines' :: Text.Text -> IO [Text.Text]
readCommandLines' cmd = do
Proc.withCreateProcess
(Proc.shell $ Text.unpack cmd)
{ Proc.delegate_ctlc = True,
Proc.std_in = Proc.NoStream,
Proc.std_out = Proc.CreatePipe,
Proc.std_err = Proc.NoStream
}
$ \_ stdout _ p -> do
_ <- Proc.waitForProcess p
Text.lines <$> maybe (pure "") Text.hGetContents stdout
processCommand :: Command -> AppEvent ()
processCommand (CmdShell waitForKey cmd) = do
cmdSubstitutions cmd >>= suspendAndRunShellCommand waitForKey
reloadDir
processCommand (CmdCommandShell cmd) = do
stdout <- cmdSubstitutions cmd >>= liftIO . readCommandLines'
forM_ stdout runIfCmd
reloadDir
where
runIfCmd (Text.stripPrefix "<daffm>" -> Just cmd') =
processCommand $ fromMaybe CmdNoop (parseCommand cmd')
runIfCmd _ = pure ()
processCommand CmdQuit = M.halt
processCommand (CmdSetCmdline txt) = enterCmdline >> cmdSubstitutions txt >>= setCmdlineText
processCommand CmdEnterCmdline = enterCmdline
processCommand CmdLeaveCmdline = leaveCmdline
processCommand CmdOpenSelection = openSelectedFile
processCommand (CmdChangeDir dir) = cmdSubstitutions dir >>= changeDir
processCommand CmdReload = reloadDir
processCommand CmdToggleSelection = toggleCurrentFileSelection
processCommand CmdClearSelection = clearFileSelections
processCommand CmdGoBack = goBackToParentDir
processCommand (CmdChain chain) = forM_ chain processCommand
processCommand (CmdSearch term) = setSearchTerm term >> applySearch >> nextSearchMatch
processCommand (CmdSearchNext change) = updateSearchIndex (+ change) >> nextSearchMatch
processCommand (CmdKeymapSet keys command) = modify $ \s -> s {stateKeyMap = Map.insert keys command $ stateKeyMap s}
processCommand CmdNoop = pure ()
evaluateCommand :: Text.Text -> AppEvent ()
evaluateCommand cmdtxt =
case parseCommand cmdtxt of
Just cmd -> processCommand cmd
Nothing -> pure ()
|