diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-12-25 12:28:47 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-12-25 13:48:00 +0530 |
| commit | b4fe44842fb6914f9060b0d018de53983b0aab0b (patch) | |
| tree | ee0d740e4500153c859d5fa02d4f6f8fa95404e6 /lib | |
| parent | 2a2ee4a51e160406522c8c3136dfbc030ad3dcdd (diff) | |
| download | daffm-b4fe44842fb6914f9060b0d018de53983b0aab0b.tar.gz daffm-b4fe44842fb6914f9060b0d018de53983b0aab0b.zip | |
Add env vars for managing escape-free commands
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Daffm/Action/Commands.hs | 12 | ||||
| -rw-r--r-- | lib/Daffm/Action/Core.hs | 21 | ||||
| -rw-r--r-- | lib/Daffm/State.hs | 37 |
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 |
