aboutsummaryrefslogtreecommitdiff
path: root/lib/Daffm/Action/Core.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Daffm/Action/Core.hs')
-rw-r--r--lib/Daffm/Action/Core.hs52
1 files changed, 43 insertions, 9 deletions
diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs
index fef6b36..f80e41a 100644
--- a/lib/Daffm/Action/Core.hs
+++ b/lib/Daffm/Action/Core.hs
@@ -6,14 +6,17 @@ module Daffm.Action.Core where
import Brick (suspendAndResume')
import qualified Brick.Widgets.List as L
+import Control.Monad (void)
import Control.Monad.State (MonadIO (liftIO), MonadState, get, gets, modify, put)
import Daffm.State
import Daffm.Types (AppEvent, AppState (..), FileInfo (..), FilePathText, FileType (..))
+import Data.Maybe (fromMaybe)
import qualified Data.Set as Set
import qualified Data.Text as Text
import System.Directory (getHomeDirectory)
+import qualified System.Exit as Proc
import System.FilePath (takeDirectory)
-import System.Process (callProcess)
+import qualified System.Process as Proc
modifyM :: (MonadState s m) => (s -> m s) -> m ()
modifyM f = get >>= f >>= put
@@ -33,8 +36,7 @@ goBackToParentDir = do
loadDir dir
changeDir :: FilePathText -> AppEvent ()
-changeDir dir = do
- loadDir dir
+changeDir = loadDir
goHome :: AppEvent ()
goHome = do
@@ -43,15 +45,47 @@ goHome = do
openSelectedFile :: AppEvent ()
openSelectedFile = do
currentFile >>= \case
- Just file -> openFile file
+ Just (FileInfo {filePath, fileType = Directory}) -> loadDir filePath
+ Just _ -> do
+ opener <- gets (fromMaybe "echo '%F' | xargs -i xdg-open {}" . stateOpenerScript)
+ cmdSubstitutions opener >>= suspendAndRunShellCommand False
Nothing -> pure ()
-openFile :: FileInfo -> AppEvent ()
-openFile (FileInfo {filePath, fileType = Directory}) = loadDir filePath
-openFile (FileInfo {filePath, fileType}) = do
+shellCommand :: String -> IO Proc.ExitCode
+shellCommand cmd = do
+ Proc.withCreateProcess
+ (Proc.shell cmd) {Proc.delegate_ctlc = True}
+ $ \_ _ _ p -> Proc.waitForProcess p
+
+cmdSubstitutions :: Text.Text -> AppEvent Text.Text
+cmdSubstitutions cmd = do
+ (AppState {stateFiles, stateCwd, stateFileSelections}) <- get
+ let file = maybe "" (filePath . snd) . L.listSelectedElement $ stateFiles
+ let escape = (\s -> "'" <> s <> "'") . Text.replace "'" "\\'"
+ let selections = Set.elems stateFileSelections
+ let selectionsOrCurrent = if Set.null stateFileSelections then [file] else selections
+ let subst =
+ Text.replace "%" file
+ . Text.replace "%d" stateCwd
+ . Text.replace "%s" (Text.unwords $ map escape selections)
+ . Text.replace "%S" (Text.dropWhileEnd (== '\n') $ Text.unlines selections)
+ . Text.replace "%f" (Text.unwords $ map escape selectionsOrCurrent)
+ . Text.replace "%F" (Text.dropWhileEnd (== '\n') $ Text.unlines selectionsOrCurrent)
+ pure . subst $ cmd
+
+-- Suspend tui and run shell command
+-- When waitForKey is true, it will prompt for a key press on success
+-- When exit code is non-zero, it will print it and prompt for key press regardless of waitForKey
+suspendAndRunShellCommand :: Bool -> Text.Text -> AppEvent ()
+suspendAndRunShellCommand waitForKey cmd = do
suspendAndResume' $ do
- putStrLn $ "Opening " <> show fileType <> ": " <> Text.unpack filePath
- callProcess "nvim" [Text.unpack filePath]
+ exitCode <- shellCommand $ Text.unpack cmd
+ case exitCode of
+ Proc.ExitFailure code -> do
+ putStrLn $ "Process exited with " <> show code
+ putStrLn "Press any key to continue" >> void getChar
+ _ | waitForKey -> putStrLn "Press any key to continue" >> void getChar
+ _ -> pure ()
currentFile :: AppEvent (Maybe FileInfo)
currentFile = do