diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-10-05 15:28:56 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-10-05 16:30:10 +0530 |
| commit | 332fed0c0936a48b5cb68ebd7b2dc4d96003008e (patch) | |
| tree | 9549cf8aababa2c47b116edfb448adf7a9d6b595 /lib/Daffm/Action | |
| parent | a4144c0c6e0d3df3740c70b9ad947642d9d48ac6 (diff) | |
| download | daffm-332fed0c0936a48b5cb68ebd7b2dc4d96003008e.tar.gz daffm-332fed0c0936a48b5cb68ebd7b2dc4d96003008e.zip | |
Add opener script in config
Diffstat (limited to '')
| -rw-r--r-- | lib/Daffm/Action/Commands.hs | 44 | ||||
| -rw-r--r-- | lib/Daffm/Action/Core.hs | 52 |
2 files changed, 43 insertions, 53 deletions
diff --git a/lib/Daffm/Action/Commands.hs b/lib/Daffm/Action/Commands.hs index e904bf5..a9b706f 100644 --- a/lib/Daffm/Action/Commands.hs +++ b/lib/Daffm/Action/Commands.hs @@ -3,11 +3,7 @@ {-# HLINT ignore "Use for_" #-} module Daffm.Action.Commands where -import Brick (suspendAndResume') import qualified Brick as M -import qualified Brick.Widgets.List as L -import Control.Monad (void) -import Control.Monad.State (get) import Daffm.Action.Cmdline import Daffm.Action.Core import Daffm.Types @@ -15,11 +11,7 @@ import Daffm.Utils (trimStart) import Data.Bifunctor (Bifunctor (second)) import Data.Char (isSpace) import Data.Maybe (fromMaybe) -import qualified Data.Set as Set import qualified Data.Text as Text -import qualified GHC.IO.Exception as Proc -import System.Exit (ExitCode) -import qualified System.Process as Proc runCmdline :: AppEvent () runCmdline = do @@ -51,20 +43,6 @@ parseCommand cmd = mkCmd . splitCmdArgs $ trimStart cmd ("selection-clear", _) -> Just CmdClearSelection _ -> Nothing --- 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 - 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 () - processCommand :: Command -> AppEvent () processCommand (CmdShell waitForKey cmd) = do cmdSubstitutions cmd >>= suspendAndRunShellCommand waitForKey @@ -81,28 +59,6 @@ processCommand CmdClearSelection = clearFileSelections processCommand CmdGoBack = goBackToParentDir processCommand CmdNoop = pure () -shellCommand :: String -> IO 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 - evaluateCommand :: Text.Text -> AppEvent () evaluateCommand cmdtxt = case parseCommand cmdtxt of 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 |
