diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e802c2..5f1e8b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog for profold +## Upcoming +* clean up code +* document functions + ## 1.0.0.0 * add readme * create project diff --git a/app/Main.hs b/app/Main.hs index 661bcd2..a3e198a 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE OverloadedStrings #-} - module Main where import Brick @@ -11,14 +9,11 @@ import Profold.App import Profold.Options import Profold.ParseProfFile -data UiName = UiViewport - deriving (Show, Eq, Ord) - main :: IO () main = do opts <- execParser options let filename = optFileName opts text <- T.readFile filename case parseProfFile filename text of - Left e -> putStrLn e + Left e -> putStrLn e Right f -> void $ defaultMain myApp $ newUiState (profInfoLines f) (profNode f) diff --git a/src/Profold/App.hs b/src/Profold/App.hs index 5d346f2..b79f3d4 100644 --- a/src/Profold/App.hs +++ b/src/Profold/App.hs @@ -1,7 +1,10 @@ {-# LANGUAGE OverloadedStrings #-} +-- | This module implements a brick application for browsing a 'LineNode' tree. + module Profold.App ( UiState + , UiName , newUiState , myApp ) where @@ -14,16 +17,24 @@ import qualified Graphics.Vty as Vty import Profold.LineNode +-- | Unique names for UI elements used in this application. data UiName = UiList deriving (Show, Eq, Ord) +-- | The state for the brick application. data UiState = UiState { uiInfo :: [T.Text] , uiTree :: LineNode , uiList :: List UiName (Path, LineNode) } deriving (Show) -newUiState :: [T.Text] -> LineNode -> UiState +-- | Create an initial ui state. +newUiState + :: [T.Text] + -- ^ A list of lines which should contain the column labels. These lines will always be displayed at the top of the screen. + -> LineNode + -- ^ The tree to display. + -> UiState newUiState info ln = toggleFold $ UiState info ln $ list UiList (flatten ln) 1 toggleFold :: UiState -> UiState @@ -74,6 +85,7 @@ myAttrMap = attrMap Vty.defAttr , ("info", Vty.defAttr `Vty.withStyle` Vty.reverseVideo) ] +-- | The brick application. myApp :: App UiState () UiName myApp = App { appDraw = myAppDraw diff --git a/src/Profold/LineNode.hs b/src/Profold/LineNode.hs index b07dab5..09aeaae 100644 --- a/src/Profold/LineNode.hs +++ b/src/Profold/LineNode.hs @@ -1,3 +1,6 @@ +-- | A module containing the tree data structure for lines in the @.prof@ file +-- and some useful functions. + module Profold.LineNode ( LineNode(..) , newLineNode @@ -6,20 +9,30 @@ module Profold.LineNode , modify ) where -import qualified Data.Text as T -import qualified Data.Vector as V +import qualified Data.Text as T +import qualified Data.Vector as V +-- | A line from the @.prof@ file and its children. data LineNode = LineNode { lineText :: T.Text + -- ^ The complete text of the line, including its indentation. , lineChildren :: V.Vector LineNode + -- ^ The line's children. , lineFolded :: Bool + -- ^ Whether the line's children are folded away. } deriving (Show) +-- | Create a new 'LineNode'. newLineNode :: T.Text -> [LineNode] -> LineNode newLineNode text children = LineNode text (V.fromList children) True +-- | A path (similar to a file path) referencing a node inside a 'LineNode' +-- tree. type Path = [Int] +-- | Convert a 'LineNode' into a flat list of itself and all visible children. +-- The list includes the 'Path' to each node. Nodes that would not be visible +-- because one of their parents is folded are not included. flatten :: LineNode -> V.Vector (Path, LineNode) flatten ln | lineFolded ln = V.singleton ([], ln) @@ -34,6 +47,8 @@ modifyAtIndex :: Int -> (a -> a) -> V.Vector a -> V.Vector a -- Yes, this function looks ugly, but it's short enough that I don't care. modifyAtIndex i f v = maybe v (\a -> v V.// [(i, f a)]) (v V.!? i) +-- | Modify a node at a specific location in the tree. Returns the original node +-- if no node exists at that path. modify :: (LineNode -> LineNode) -> Path -> LineNode -> LineNode modify f [] ln = f ln modify f (i:is) ln = diff --git a/src/Profold/Options.hs b/src/Profold/Options.hs index 9d3b10e..64ee926 100644 --- a/src/Profold/Options.hs +++ b/src/Profold/Options.hs @@ -1,3 +1,5 @@ +-- | A module for parsing command line options. + module Profold.Options ( Options(..) , options @@ -5,13 +7,16 @@ module Profold.Options import Options.Applicative +-- | The command line options. newtype Options = Options { optFileName :: String + -- ^ Name of the @.prof@ file to open and parse. } deriving (Show) parser :: Parser Options parser = Options <$> strArgument (help "Path to the .prof file" <> metavar "FILE") +-- | A parser for the command line options. options :: ParserInfo Options options = info (helper <*> parser) fullDesc diff --git a/src/Profold/ParseProfFile.hs b/src/Profold/ParseProfFile.hs index bf3809d..c7412cb 100644 --- a/src/Profold/ParseProfFile.hs +++ b/src/Profold/ParseProfFile.hs @@ -1,5 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} +-- | This module contains a parser for parsing @.prof@ files. + module Profold.ParseProfFile ( ProfFile(..) , parseProfFile @@ -13,6 +15,8 @@ import Text.Megaparsec.Char import Profold.LineNode +-- | A @.prof@ file includes a few lines at the beginning that contain the +-- column names. data ProfFile = ProfFile { profInfoLines :: [T.Text] , profNode :: LineNode @@ -48,6 +52,8 @@ profFile = do node <- lineNode "" pure $ ProfFile info node +-- | A parser for @.prof@ files. If the file could not be parsed, returns a +-- @Left errorMessage@. parseProfFile :: String -> T.Text -> Either String ProfFile parseProfFile filename text = case parse profFile filename text of Left e -> Left $ errorBundlePretty e