Skip to content
Snippets Groups Projects
Commit 1afa6a11 authored by David Eichmann's avatar David Eichmann :lifter:
Browse files

TUI: periodically poll for debuggees

This uses the new convention of placing sockets in `socketDirectory`
parent ac8ad4c5
Branches master
No related tags found
No related merge requests found
...@@ -23,10 +23,12 @@ executable tui ...@@ -23,10 +23,12 @@ executable tui
build-depends: base >=4.10 && <5 build-depends: base >=4.10 && <5
, brick , brick
, containers , containers
, directory
, filepath
, ghc-debug-client
, microlens-platform , microlens-platform
, text , text
, vty , vty
, ghc-debug-client
hs-source-dirs: src hs-source-dirs: src
default-language: Haskell2010 default-language: Haskell2010
ghc-options: -threaded ghc-options: -threaded
{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedLists #-} {-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Main where module Main where
import Control.Applicative
import Brick import Control.Monad (forever)
import Brick.BChan import Control.Monad.IO.Class
import Brick.Widgets.List import Control.Concurrent
import Data.Sequence import qualified Data.List as List
import Data.Sequence as Seq
import Data.Text import Data.Text
import Graphics.Vty(defaultConfig, mkVty, defAttr) import Graphics.Vty(defaultConfig, mkVty, defAttr)
import qualified Graphics.Vty.Input.Events as Vty import qualified Graphics.Vty.Input.Events as Vty
import Graphics.Vty.Input.Events (Key(..)) import Graphics.Vty.Input.Events (Key(..))
import Lens.Micro.Platform import Lens.Micro.Platform
import System.Directory
import System.FilePath
import Brick
import Brick.BChan
import Brick.Widgets.Border import Brick.Widgets.Border
import Brick.Widgets.List
import GHC.Debug.Client import GHC.Debug.Client
-- data AppState = AppState
-- -- | Known debuggees that we could connect to.
-- { stateKnownDebuggees :: [Debuggee]
-- , selectedDebuggee :: Maybe Debuggee
-- }
-- data Debuggee = Debuggee FilePath
-- data Event
-- = Closed
-- | SetKnownDebuggees [Debuggee]
-- -- | SetSelectedDebuggee Debuggee
-- | NoOp
-- view' :: AppState -> AppView Window Event
-- view' state
-- = bin Window
-- [ #title := "ghc-debug"
-- , on #deleteEvent (const (True, Closed))
-- , #widthRequest := 400
-- , #heightRequest := 300
-- ]
-- $ container Box []
-- [ -- widget ComboBox [#model := [("Hello ghc-debug World!" :: String)]]
-- NoOp <$ BoxChild defaultBoxChildProperties (CB.comboBox [] [(1 :: Int, "adsfadsf1"), (2, "2")])
-- ]
-- update' :: AppState -> Event -> Transition AppState Event
-- -- update' AppState {..} (Greet who) =
-- -- Transition AppState { greetings = greetings <> [who] } (pure Nothing)
-- update' _ Closed = Exit
data Event data Event
= PollTick -- Used to perform arbitrary polling based tasks e.g. looking for new debuggees
data Name data Name
= Main = Main
...@@ -59,36 +36,60 @@ data Name ...@@ -59,36 +36,60 @@ data Name
deriving (Eq, Ord, Show) deriving (Eq, Ord, Show)
data AppState = AppState data AppState = AppState
{ _options :: GenericList Name Seq Text { _knownDebuggees :: GenericList Name Seq (Text, FilePath) -- ^ File name and full path
} }
makeLenses ''AppState makeLenses ''AppState
myAppDraw :: AppState -> [Widget Name] myAppDraw :: AppState -> [Widget Name]
myAppDraw (AppState options) = myAppDraw appState =
[ borderWithLabel (txt "ghc-debug") [ borderWithLabel (txt "ghc-debug")
$ padAll 1 $ padAll 1
$ vBox $ vBox
[ txt "Hello Brick World!" [ txt $ "Select a process to debug (" <> pack (show nKnownDebuggees) <> " found):"
, renderList , renderList
(\elIsSelected el -> hBox (\elIsSelected (el, _) -> hBox
[ txt $ if elIsSelected then "*" else " " [ txt $ if elIsSelected then "*" else " "
, txt " " , txt " "
, txt el , txt el
] ]
) )
True True
options (appState^.knownDebuggees)
] ]
] ]
where
nKnownDebuggees = Seq.length $ appState^.knownDebuggees.listElementsL
myAppHandleEvent :: AppState -> BrickEvent Name e -> EventM Name (Next AppState) myAppHandleEvent :: AppState -> BrickEvent Name Event -> EventM Name (Next AppState)
myAppHandleEvent appState brickEvent = case brickEvent of myAppHandleEvent appState brickEvent = case brickEvent of
VtyEvent (Vty.EvKey KEsc []) -> halt appState VtyEvent (Vty.EvKey KEsc []) -> halt appState
VtyEvent event -> do VtyEvent event -> do
handleListEvent event (appState^.options) handleListEvent event (appState^.knownDebuggees)
newOptions <- handleListEvent event (appState^.options) newOptions <- handleListEvent event (appState^.knownDebuggees)
continue $ appState & options .~ newOptions continue $ appState & knownDebuggees .~ newOptions
AppEvent event -> case event of
PollTick -> do
-- Poll for debuggees
knownDebuggees' <- liftIO $ do
dir :: FilePath <- socketDirectory
debuggeeSockets :: [FilePath] <- listDirectory dir <|> return []
let currentSelectedPathMay :: Maybe FilePath
currentSelectedPathMay = fmap (snd . snd) (listSelectedElement (appState^.knownDebuggees))
newSelection :: Maybe Int
newSelection = do
currentSelectedPath <- currentSelectedPathMay
List.findIndex (currentSelectedPath ==) debuggeeSockets
return $ listReplace
(fromList [(pack (dir </> socket), socket) | socket <- debuggeeSockets])
newSelection
(appState^.knownDebuggees)
continue $ appState & knownDebuggees .~ knownDebuggees'
_ -> do _ -> do
continue appState continue appState
...@@ -101,6 +102,9 @@ myAppAttrMap _appState = attrMap defAttr [] ...@@ -101,6 +102,9 @@ myAppAttrMap _appState = attrMap defAttr []
main :: IO () main :: IO ()
main = do main = do
eventChan <- newBChan 10 eventChan <- newBChan 10
forkIO $ forever $ do
writeBChan eventChan PollTick
threadDelay 2000000
let buildVty = mkVty defaultConfig let buildVty = mkVty defaultConfig
initialVty <- buildVty initialVty <- buildVty
let app :: App AppState Event Name let app :: App AppState Event Name
...@@ -112,6 +116,8 @@ main = do ...@@ -112,6 +116,8 @@ main = do
, appAttrMap = myAppAttrMap , appAttrMap = myAppAttrMap
} }
initialState = AppState initialState = AppState
{ _knownDebuggees = list Main_FileList [] 1
}
_finalState <- customMain initialVty buildVty _finalState <- customMain initialVty buildVty
(Just eventChan) app (initialState (list Main_FileList ["A", "BB", "CC"] 1)) (Just eventChan) app initialState
return () return ()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment