aboutsummaryrefslogtreecommitdiff
path: root/lib/Daffm
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-12-25 12:28:47 +0530
committerAkshay Nair <phenax5@gmail.com>2025-12-25 13:48:00 +0530
commitb4fe44842fb6914f9060b0d018de53983b0aab0b (patch)
treeee0d740e4500153c859d5fa02d4f6f8fa95404e6 /lib/Daffm
parent2a2ee4a51e160406522c8c3136dfbc030ad3dcdd (diff)
downloaddaffm-b4fe44842fb6914f9060b0d018de53983b0aab0b.tar.gz
daffm-b4fe44842fb6914f9060b0d018de53983b0aab0b.zip
Add env vars for managing escape-free commands
Diffstat (limited to '')
-rw-r--r--lib/Daffm/Action/Commands.hs12
-rw-r--r--lib/Daffm/Action/Core.hs21
-rw-r--r--lib/Daffm/State.hs37
3 files changed, 48 insertions, 22 deletions
diff --git a/lib/Daffm/Action/Commands.hs b/lib/Daffm/Action/Commands.hs
index 9a90f93..39534e1 100644
--- a/lib/Daffm/Action/Commands.hs
+++ b/lib/Daffm/Action/Commands.hs
@@ -21,6 +21,7 @@ import qualified Data.Text as Text
import qualified Data.Text.IO as Text
import qualified System.Process as Proc
import Text.Read (readMaybe)
+import System.Environment (getEnvironment)
runCmdline :: AppEvent ()
runCmdline = do
@@ -67,14 +68,16 @@ parseCommand cmd = mkCmd . splitCmdArgs $ trimStart cmd
("", _) -> Nothing
(cmd', args) -> Just $ CmdCustom cmd' args
-readCommandLines :: Text.Text -> IO [Text.Text]
-readCommandLines cmd = do
+readCommandLines :: Map.Map String String -> Text.Text -> IO [Text.Text]
+readCommandLines env cmd = do
+ cmdEnv <- (++ Map.toList env) <$> getEnvironment
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
+ Proc.std_err = Proc.NoStream,
+ Proc.env = Just cmdEnv
}
$ \_ stdout _ p -> do
_ <- Proc.waitForProcess p
@@ -88,7 +91,8 @@ processCommand (CmdShell waitForKey cmd) args = do
cmdSubstitutions (argSubst args cmd) >>= suspendAndRunShellCommand waitForKey
reloadDir
processCommand (CmdCommandShell cmd) args = do
- stdout <- cmdSubstitutions (argSubst args cmd) >>= liftIO . readCommandLines
+ env <- gets geCommandEnvFromState
+ stdout <- cmdSubstitutions (argSubst args cmd) >>= liftIO . readCommandLines env
forM_ stdout runIfCmd
reloadDir
where
diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs
index ba50638..1ff5737 100644
--- a/lib/Daffm/Action/Core.hs
+++ b/lib/Daffm/Action/Core.hs
@@ -49,7 +49,7 @@ openSelectedFile = do
Just (FileInfo {filePath, fileType = Directory}) -> loadDir filePath
Just (FileInfo {filePath, fileLinkType = Just Directory}) -> loadDir filePath
Just _ -> do
- opener <- gets (fromMaybe "echo '%F' | xargs -i xdg-open {}" . stateOpenerScript)
+ opener <- gets (fromMaybe "echo \"$files\" | xargs -i xdg-open {}" . stateOpenerScript)
cmdSubstitutions opener >>= suspendAndRunShellCommand False
Nothing -> pure ()
@@ -74,19 +74,32 @@ cmdSubstitutions cmd = gets (`substitute` cmd)
-- 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
+ env <- gets geCommandEnvFromState
suspendAndResume' $ do
- shellCommand (Text.unpack cmd) Map.empty >>= \case
+ shellCommand (Text.unpack cmd) env >>= \case
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 ()
+geCommandEnvFromState :: AppState -> Map.Map String String
+geCommandEnvFromState (AppState {stateFileSelections, stateFiles}) = do
+ Map.fromList
+ [ ("files", Text.unpack $ Text.dropWhileEnd (== '\n') $ Text.unlines selectionsOrCursor),
+ ("selections", Text.unpack $ Text.dropWhileEnd (== '\n') $ Text.unlines selections),
+ ("cursor", Text.unpack cursorFile)
+ ]
+ where
+ cursorFile = maybe "" (filePath . snd) . L.listSelectedElement $ stateFiles
+ selections = Set.elems stateFileSelections
+ selectionsOrCursor = if Set.null stateFileSelections then [cursorFile] else selections
+
shellCommand :: String -> Map.Map String String -> IO Proc.ExitCode
shellCommand cmd env = do
- currentEnv <- getEnvironment
+ cmdEnv <- (++ Map.toList env) <$> getEnvironment
Proc.withCreateProcess
- (Proc.shell cmd) {Proc.delegate_ctlc = True, Proc.env = Just $ currentEnv ++ Map.toList env}
+ (Proc.shell cmd) {Proc.delegate_ctlc = True, Proc.env = Just cmdEnv}
$ \_ _ _ p -> Proc.waitForProcess p
currentFile :: AppEvent (Maybe FileInfo)
diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs
index bc91ecb..9b3d81d 100644
--- a/lib/Daffm/State.hs
+++ b/lib/Daffm/State.hs
@@ -28,21 +28,30 @@ mkEditor = Editor.editor FocusCmdline (Just 1)
mkEmptyAppState :: Configuration -> AppState
mkEmptyAppState config =
- AppState
- { stateFiles = L.list FocusMain (Vec.fromList []) 1,
- stateMessage = Nothing,
- stateCmdlineEditor = mkEditor "",
- stateFocusTarget = FocusMain,
- stateListPositionHistory = Map.empty,
- stateFileSelections = Set.empty,
- stateCwd = "",
- stateKeyMap = configKeymap config,
+ applyConfigToState config $
+ AppState
+ { stateFiles = L.list FocusMain (Vec.fromList []) 1,
+ stateMessage = Nothing,
+ stateCmdlineEditor = mkEditor "",
+ stateFocusTarget = FocusMain,
+ stateListPositionHistory = Map.empty,
+ stateFileSelections = Set.empty,
+ stateCwd = "",
+ stateKeyMap = Map.empty,
+ stateOpenerScript = Nothing,
+ stateKeySequence = [],
+ stateSearchTerm = Nothing,
+ stateSearchMatches = Vec.empty,
+ stateCustomCommands = Map.empty,
+ stateSearchIndex = 0
+ }
+
+applyConfigToState :: Configuration -> AppState -> AppState
+applyConfigToState config state =
+ state
+ { stateKeyMap = configKeymap config,
stateOpenerScript = configOpener config,
- stateKeySequence = [],
- stateSearchTerm = Nothing,
- stateSearchMatches = Vec.empty,
- stateCustomCommands = configCommands config,
- stateSearchIndex = 0
+ stateCustomCommands = configCommands config
}
toggleSetItem :: (Ord a) => a -> Set.Set a -> Set.Set a