i3ipc 0.1.0.0 → 0.1.0.1
raw patch · 3 files changed
+61/−18 lines, 3 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ I3IPC: subscribeM :: MonadIO m => (Either String Event -> m ()) -> [Subscribe] -> m ()
Files
- README.md +25/−1
- i3ipc.cabal +1/−1
- src/I3IPC.hs +35/−16
README.md view
@@ -4,6 +4,8 @@ Haskell type-safe bindings for working with i3 using it's unix socket IPC +## Subscribing+ Subscribe to events: ```haskell@@ -15,6 +17,26 @@ main = subscribe print [Sub.Workspace, Sub.Window] ``` +An example of explicitly matching on some events and printing their fields:++```haskell+import qualified I3IPC.Subscribe as Sub+import I3IPC.Event+import I3IPC ( subscribe )++main :: IO ()+main = subscribe handle [Sub.Workspace, Sub.Window]+ where+ handle :: Either String Event -> IO ()+ handle (Right evt) = case evt of+ Workspace WorkspaceEvent { wrk_current } -> print wrk_current+ Window WindowEvent { win_container } -> print win_container+ _ -> error "No other event types"+ handle (Left err) = error err+```++## Sending Messages+ Sending Messages to i3: ```haskell@@ -25,7 +47,7 @@ main :: IO () main = do soc <- connecti3- print getWorkspaces+ print $ getWorkspaces soc ``` Alternatively, you can ignore the convenience functions and construct these messages yourself:@@ -41,5 +63,7 @@ soc <- connecti3 print $ Msg.sendMsg soc Msg.Workspaces >> receiveMsg soc ```++## Community I'm happy to take PRs or suggestions, or simply fix issues for this library.
i3ipc.cabal view
@@ -1,5 +1,5 @@ name: i3ipc-version: 0.1.0.0+version: 0.1.0.1 description: Library for controlling i3 through it's IPC. i3 communicates using a JSON interface over a unix socket. For JSON parsing I'm using Aeson. I've written out all the records and types to allow anyone to easily interact with i3 from a Haskell application.
src/I3IPC.hs view
@@ -21,6 +21,7 @@ getSocketPath , Response(..) , subscribe+ , subscribeM , receive , receive' , receiveMsg@@ -60,6 +61,7 @@ import qualified I3IPC.Event as Evt import I3IPC.Reply +import Control.Monad.IO.Class import System.Environment ( lookupEnv ) import Data.Maybe ( isJust ) import Data.Semigroup ( (<>) )@@ -100,29 +102,38 @@ -- | Subscribe with a list of 'I3IPC.Subscribe.Subscribe' types, and subscribe will to respond with specific 'I3IPC.Event.Event' subscribe :: (Either String Evt.Event -> IO ()) -> [Sub.Subscribe] -> IO () subscribe handle subtypes = do- soc <- socket AF_UNIX Stream 0- addr <- getSocketPath- case addr of- Nothing -> putStrLn "Failed to get i3 socket path" >> exitFailure- Just addr' ->- connect soc (SockAddrUnix $ BL.unpack addr')- >> Msg.sendMsgPayload soc Msg.Subscribe (encode subtypes)- >> receiveMsg soc- >> handleSoc soc- >> close soc+ soc <- connecti3+ Msg.sendMsgPayload soc Msg.Subscribe (encode subtypes)+ >> receiveMsg soc+ >> handleSoc soc+ >> close soc where handleSoc soc = do r <- receiveEvent soc handle r handleSoc soc +-- | A version of 'subscribe' that allows the use of any monad transformer on top of MonadIO+subscribeM+ :: MonadIO m => (Either String Evt.Event -> m ()) -> [Sub.Subscribe] -> m ()+subscribeM handle subtypes = do+ soc <- liftIO connecti3+ liftIO+ $ Msg.sendMsgPayload soc Msg.Subscribe (encode subtypes)+ >> receiveMsg soc+ >> pure ()+ handleSoc soc >> liftIO (close soc)+ where+ handleSoc soc = do+ r <- liftIO $ receiveEvent soc+ handle r+ handleSoc soc -- | Connect to an i3 socket and return it connecti3 :: IO Socket connecti3 = do- soc <- socket AF_UNIX Stream 0- addr <- getSocketPath- case addr of+ soc <- socket AF_UNIX Stream 0+ getSocketPath >>= \case Nothing -> putStrLn "Failed to get i3 socket path" >> exitFailure Just addr' -> do connect soc (SockAddrUnix $ BL.unpack addr')@@ -291,11 +302,19 @@ -- -- Commonly, you just want to subscribe to a set of event types and do something with the response: ----- > import qualified I3IPC.Subscribe as Sub--- > import I3IPC ( subscribe )+-- > import qualified I3IPC.Subscribe as Sub+-- > import I3IPC.Event+-- > import I3IPC ( subscribe ) -- > -- > main :: IO ()--- > main = subscribe print [Sub.Workspace, Sub.Window]+-- > main = subscribe handle [Sub.Workspace, Sub.Window]+-- > where+-- > handle :: Either String Event -> IO ()+-- > handle (Right evt) = case evt of+-- > Workspace WorkspaceEvent { wrk_current } -> print wrk_current+-- > Window WindowEvent { win_container } -> print win_container+-- > _ -> error "No other event types"+-- > handle (Left err) = error err -- -- $msg