xmonad-config/lib/XMonad/Internal/Shell.hs

106 lines
2.7 KiB
Haskell
Raw Normal View History

{-# LANGUAGE OverloadedStrings #-}
2020-04-01 22:06:00 -04:00
--------------------------------------------------------------------------------
-- | Functions for formatting and spawning shell commands
2020-04-01 20:17:47 -04:00
module XMonad.Internal.Shell
( fmtCmd
2020-04-01 20:17:47 -04:00
, spawnCmd
2022-12-29 00:06:55 -05:00
, spawn
2021-06-17 01:17:59 -04:00
, doubleQuote
, singleQuote
2021-06-19 00:17:47 -04:00
, skip
2022-12-29 00:06:55 -05:00
, runProcessX
, spawnAt
, proc'
, shell'
, createProcess'
2020-04-01 20:17:47 -04:00
, (#!&&)
, (#!||)
, (#!|)
2020-04-01 20:17:47 -04:00
, (#!>>)
) where
2020-03-18 12:17:39 -04:00
import Control.Monad.IO.Class
2022-12-29 00:06:55 -05:00
import RIO
import qualified RIO.Text as T
2022-12-29 00:06:55 -05:00
import System.Process
import qualified XMonad.Core as X
2020-03-28 18:38:38 -04:00
2020-04-01 22:06:00 -04:00
--------------------------------------------------------------------------------
-- | Opening subshell
2020-03-18 12:17:39 -04:00
2022-12-29 00:06:55 -05:00
withDefaultSignalHandlers :: IO a -> IO a
withDefaultSignalHandlers =
bracket_ X.uninstallSignalHandlers X.installSignalHandlers
addGroupSession :: CreateProcess -> CreateProcess
addGroupSession cp = cp { create_group = True, new_session = True }
createProcess' :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
createProcess' = withDefaultSignalHandlers . createProcess
readProcessX :: CreateProcess -> String -> IO (ExitCode, T.Text, T.Text)
readProcessX c i = withDefaultSignalHandlers $ do
(r, e, p) <- readCreateProcessWithExitCode c i
return (r, T.pack e, T.pack p)
runProcessX :: CreateProcess -> String -> IO ExitCode
runProcessX c i = (\(r, _, _) -> r) <$> readProcessX c i
shell' :: String -> CreateProcess
shell' = addGroupSession . shell
proc' :: FilePath -> [String] -> CreateProcess
proc' cmd args = addGroupSession $ proc cmd args
spawn :: MonadIO m => String -> m ()
spawn = liftIO . void . createProcess' . shell'
spawnAt :: MonadIO m => FilePath -> String -> m ()
spawnAt fp cmd = liftIO $ void $ createProcess' $ (shell' cmd) { cwd = Just fp }
spawnCmd :: MonadIO m => FilePath -> [T.Text] -> m ()
spawnCmd cmd args = spawn $ T.unpack $ fmtCmd cmd args
2020-03-18 12:17:39 -04:00
2020-04-01 22:06:00 -04:00
--------------------------------------------------------------------------------
-- | Formatting commands
fmtCmd :: FilePath -> [T.Text] -> T.Text
fmtCmd cmd args = T.unwords $ T.pack cmd : args
op :: T.Text -> T.Text -> T.Text -> T.Text
op a x b = T.unwords [a, x, b]
2020-04-01 22:06:00 -04:00
(#!&&) :: T.Text -> T.Text -> T.Text
cmdA #!&& cmdB = op cmdA "&&" cmdB
2020-03-18 12:17:39 -04:00
infixr 0 #!&&
(#!|) :: T.Text -> T.Text -> T.Text
cmdA #!| cmdB = op cmdA "|" cmdB
infixr 0 #!|
(#!||) :: T.Text -> T.Text -> T.Text
cmdA #!|| cmdB = op cmdA "||" cmdB
2020-03-18 12:17:39 -04:00
infixr 0 #!||
(#!>>) :: T.Text -> T.Text -> T.Text
cmdA #!>> cmdB = op cmdA ";" cmdB
2020-03-18 12:17:39 -04:00
infixr 0 #!>>
2021-06-17 01:17:59 -04:00
doubleQuote :: T.Text -> T.Text
doubleQuote s = T.concat ["\"", s, "\""]
2021-06-17 01:17:59 -04:00
singleQuote :: T.Text -> T.Text
singleQuote s = T.concat ["'", s, "'"]
skip :: Monad m => m ()
skip = return ()