Implement the rest
This is still quite buggy, but now the basics are in place.
This commit is contained in:
parent
fd10a59b86
commit
64aa07e04c
5 changed files with 103 additions and 24 deletions
22
app/Main.hs
22
app/Main.hs
|
|
@ -4,16 +4,19 @@ module Main where
|
||||||
|
|
||||||
import Brick
|
import Brick
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import qualified Data.Text.IO as T
|
||||||
import qualified Graphics.Vty as Vty
|
import qualified Graphics.Vty as Vty
|
||||||
|
import Options.Applicative
|
||||||
|
|
||||||
import Profold.LineNode
|
import Profold.Options
|
||||||
|
import Profold.ParseProfFile
|
||||||
import Profold.UiState
|
import Profold.UiState
|
||||||
|
|
||||||
data UiName = UiViewport
|
data UiName = UiViewport
|
||||||
deriving (Show, Eq, Ord)
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
myAppDraw :: UiState -> [Widget UiName]
|
myAppDraw :: UiState -> [Widget UiName]
|
||||||
myAppDraw s = [viewport UiViewport Vertical $ renderUiState s]
|
myAppDraw s = [renderUiState UiViewport s]
|
||||||
|
|
||||||
myHandleEvent :: UiState -> BrickEvent n e -> EventM n (Next UiState)
|
myHandleEvent :: UiState -> BrickEvent n e -> EventM n (Next UiState)
|
||||||
myHandleEvent s (VtyEvent (Vty.EvKey Vty.KEsc _)) = halt s
|
myHandleEvent s (VtyEvent (Vty.EvKey Vty.KEsc _)) = halt s
|
||||||
|
|
@ -32,7 +35,7 @@ myAttrMap = attrMap Vty.defAttr
|
||||||
|
|
||||||
myApp :: App UiState () UiName
|
myApp :: App UiState () UiName
|
||||||
myApp = App
|
myApp = App
|
||||||
{ appDraw = \s -> [renderUiState s]
|
{ appDraw = myAppDraw
|
||||||
, appChooseCursor = neverShowCursor
|
, appChooseCursor = neverShowCursor
|
||||||
, appHandleEvent = myHandleEvent
|
, appHandleEvent = myHandleEvent
|
||||||
, appStartEvent = pure
|
, appStartEvent = pure
|
||||||
|
|
@ -40,7 +43,12 @@ myApp = App
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = void $ defaultMain myApp $ newUiState $ newLineNode "Hello world"
|
main = do
|
||||||
[ newLineNode " Child" []
|
opts <- execParser options
|
||||||
, newLineNode " More children" []
|
let filename = optFileName opts
|
||||||
]
|
text <- T.readFile filename
|
||||||
|
case parseProfFile filename text of
|
||||||
|
Left e -> putStrLn e
|
||||||
|
Right f -> do
|
||||||
|
print f
|
||||||
|
void $ defaultMain myApp $ newUiState (profInfoLines f) (profNode f)
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ extra-source-files:
|
||||||
dependencies:
|
dependencies:
|
||||||
- base >= 4.7 && < 5
|
- base >= 4.7 && < 5
|
||||||
- brick
|
- brick
|
||||||
- containers
|
|
||||||
- megaparsec
|
- megaparsec
|
||||||
|
- optparse-applicative
|
||||||
- text
|
- text
|
||||||
- vector
|
- vector
|
||||||
- vty
|
- vty
|
||||||
|
|
|
||||||
17
src/Profold/Options.hs
Normal file
17
src/Profold/Options.hs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
module Profold.Options
|
||||||
|
( Options(..)
|
||||||
|
, options
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Options.Applicative
|
||||||
|
|
||||||
|
newtype Options = Options
|
||||||
|
{ optFileName :: String
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
parser :: Parser Options
|
||||||
|
parser = Options
|
||||||
|
<$> strArgument (help "Path to the .prof file" <> metavar "FILE")
|
||||||
|
|
||||||
|
options :: ParserInfo Options
|
||||||
|
options = info (helper <*> parser) fullDesc
|
||||||
54
src/Profold/ParseProfFile.hs
Normal file
54
src/Profold/ParseProfFile.hs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
module Profold.ParseProfFile
|
||||||
|
( ProfFile(..)
|
||||||
|
, parseProfFile
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import Data.Void
|
||||||
|
import Text.Megaparsec
|
||||||
|
import Text.Megaparsec.Char
|
||||||
|
|
||||||
|
import Profold.LineNode
|
||||||
|
|
||||||
|
data ProfFile = ProfFile
|
||||||
|
{ profInfoLines :: [T.Text]
|
||||||
|
, profNode :: LineNode
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
type Parser = Parsec Void T.Text
|
||||||
|
|
||||||
|
line :: Parser T.Text
|
||||||
|
line = label "line" $ takeWhileP Nothing (/= '\n') <* newline
|
||||||
|
|
||||||
|
skipUntilTheInterestingStuff :: Parser ()
|
||||||
|
skipUntilTheInterestingStuff = void $ skipManyTill line newLines
|
||||||
|
where
|
||||||
|
newLines = try $ newline >> newline
|
||||||
|
|
||||||
|
lineWithIndentation :: T.Text -> Parser T.Text
|
||||||
|
lineWithIndentation indentation = do
|
||||||
|
void $ string indentation
|
||||||
|
l <- line
|
||||||
|
pure $ indentation <> l
|
||||||
|
|
||||||
|
lineNode :: T.Text -> Parser LineNode
|
||||||
|
lineNode indentation = do
|
||||||
|
text <- lineWithIndentation indentation
|
||||||
|
children <- many $ lineNode $ indentation <> " "
|
||||||
|
pure $ newLineNode text children
|
||||||
|
|
||||||
|
profFile :: Parser ProfFile
|
||||||
|
profFile = do
|
||||||
|
skipUntilTheInterestingStuff
|
||||||
|
info <- count 2 line
|
||||||
|
void newline
|
||||||
|
node <- lineNode ""
|
||||||
|
pure $ ProfFile info node
|
||||||
|
|
||||||
|
parseProfFile :: String -> T.Text -> Either String ProfFile
|
||||||
|
parseProfFile filename text = case parse profFile filename text of
|
||||||
|
Left e -> Left $ errorBundlePretty e
|
||||||
|
Right f -> Right f
|
||||||
|
|
@ -13,18 +13,20 @@ module Profold.UiState
|
||||||
|
|
||||||
import Brick
|
import Brick
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import qualified Data.Text as T
|
||||||
import qualified Data.Vector as V
|
import qualified Data.Vector as V
|
||||||
|
|
||||||
import Profold.LineNode
|
import Profold.LineNode
|
||||||
import Profold.Util
|
import Profold.Util
|
||||||
|
|
||||||
data UiState = UiState
|
data UiState = UiState
|
||||||
{ uiTree :: LineNode
|
{ uiInfo :: [T.Text]
|
||||||
|
, uiTree :: LineNode
|
||||||
, uiFocused :: Path
|
, uiFocused :: Path
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
|
|
||||||
newUiState :: LineNode -> UiState
|
newUiState :: [T.Text] -> LineNode -> UiState
|
||||||
newUiState ln = UiState ln []
|
newUiState info ln = UiState info ln []
|
||||||
|
|
||||||
moveFocusUp :: UiState -> UiState
|
moveFocusUp :: UiState -> UiState
|
||||||
moveFocusUp s =
|
moveFocusUp s =
|
||||||
|
|
@ -50,24 +52,22 @@ toggleFold s =
|
||||||
| V.null $ lineChildren ln = ln
|
| V.null $ lineChildren ln = ln
|
||||||
| otherwise = ln {lineFolded = not $ lineFolded ln}
|
| otherwise = ln {lineFolded = not $ lineFolded ln}
|
||||||
|
|
||||||
wrapFolded :: Bool -> Widget n -> Widget n
|
|
||||||
wrapFolded False widget = withDefAttr "unfolded" $ str " " <+> widget
|
|
||||||
wrapFolded True widget = withDefAttr "folded" $ str "+" <+> widget
|
|
||||||
|
|
||||||
wrapFocused :: Bool -> Widget n -> Widget n
|
wrapFocused :: Bool -> Widget n -> Widget n
|
||||||
wrapFocused False = withDefAttr "unfocused"
|
wrapFocused False = withDefAttr "unfocused"
|
||||||
wrapFocused True = visible . withDefAttr "focused"
|
wrapFocused True = visible . withDefAttr "focused"
|
||||||
|
|
||||||
renderLine :: Bool -> LineNode -> Widget n
|
renderLine :: Bool -> LineNode -> Widget n
|
||||||
renderLine focused ln =
|
renderLine focused ln =
|
||||||
wrapFocused focused $
|
let prefix
|
||||||
wrapFolded foldedWithChildren $ padRight Max $ txt $ lineText ln
|
| V.null $ lineChildren ln = " "
|
||||||
where
|
| lineFolded ln = "+"
|
||||||
foldedWithChildren = lineFolded ln && not (V.null $ lineChildren ln)
|
| otherwise = "-"
|
||||||
|
in wrapFocused focused $ padRight Max $ str prefix <+> txt (lineText ln)
|
||||||
|
|
||||||
renderUiState :: UiState -> Widget n
|
renderUiState :: (Show n, Ord n) => n -> UiState -> Widget n
|
||||||
renderUiState s =
|
renderUiState n s =
|
||||||
let flat = V.toList $ flatten $ uiTree s
|
let info = vBox $ map txt $ uiInfo s
|
||||||
|
flat = V.toList $ flatten $ uiTree s
|
||||||
focused = uiFocused s
|
focused = uiFocused s
|
||||||
rendered = map (\(p, ln) -> renderLine (p == focused) ln) flat
|
rendered = map (\(p, ln) -> renderLine (p == focused) ln) flat
|
||||||
in vBox rendered
|
in info <=> viewport n Vertical (vBox rendered)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue