From 9f2bb3c45b0920267ef69b718bafdba370d69d73 Mon Sep 17 00:00:00 2001 From: CrystalSplitter Date: Fri, 19 Jan 2024 01:27:45 -0800 Subject: [PATCH] Reorganise modules to create the Ghcitui.Brick module --- app/Main.hs | 17 +++-- ghcitui.cabal | 67 +++++++++---------- lib/ghcitui-brick/Ghcitui/Brick.hs | 10 +++ .../ghcitui-brick/Ghcitui/Brick}/AppConfig.hs | 10 ++- .../Ghcitui/Brick}/AppInterpState.hs | 4 +- .../ghcitui-brick/Ghcitui/Brick}/AppState.hs | 11 +-- .../Ghcitui/Brick}/AppTopLevel.hs | 2 +- .../ghcitui-brick/Ghcitui/Brick}/BrickUI.hs | 18 ++--- .../Ghcitui/Brick}/DrawSourceViewer.hs | 8 +-- .../ghcitui-brick/Ghcitui/Brick}/Events.hs | 36 +++++----- .../ghcitui-brick/Ghcitui/Brick}/HelpText.hs | 2 +- .../Ghcitui/Brick}/SplashTextEmbed.hs | 2 +- 12 files changed, 100 insertions(+), 87 deletions(-) create mode 100644 lib/ghcitui-brick/Ghcitui/Brick.hs rename {app => lib/ghcitui-brick/Ghcitui/Brick}/AppConfig.hs (89%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/AppInterpState.hs (97%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/AppState.hs (97%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/AppTopLevel.hs (85%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/BrickUI.hs (96%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/DrawSourceViewer.hs (97%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/Events.hs (94%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/HelpText.hs (83%) rename {app => lib/ghcitui-brick/Ghcitui/Brick}/SplashTextEmbed.hs (81%) diff --git a/app/Main.hs b/app/Main.hs index f3fade8..95838b7 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -10,8 +10,7 @@ import Control.Applicative (many) import qualified Data.Text as T import qualified Options.Applicative as Opt -import qualified AppConfig -import BrickUI (launchBrick) +import qualified Ghcitui.Brick as GB -- | Holds passed in command line options. data CmdOptions = CmdOptions @@ -85,16 +84,16 @@ main = do putStrLn $ programName <> " " <> programVersion else do let conf = - AppConfig.defaultConfig - { AppConfig.getDebugConsoleOnStart = debugConsole opts - , AppConfig.getVerbosity = verbosity opts - , AppConfig.getDebugLogPath = debugLogPath opts - , AppConfig.getCmd = + GB.defaultConfig + { GB.getDebugConsoleOnStart = debugConsole opts + , GB.getVerbosity = verbosity opts + , GB.getDebugLogPath = debugLogPath opts + , GB.getCmd = if T.null $ cmd opts - then AppConfig.getCmd AppConfig.defaultConfig + then GB.getCmd GB.defaultConfig else cmd opts } - launchBrick conf (target opts) (workdir opts) + GB.launchBrick conf (target opts) (workdir opts) where programName = "ghcitui" programDescription = Opt.progDesc (programName <> ": A TUI interface for GHCi") diff --git a/ghcitui.cabal b/ghcitui.cabal index 5f5ab58..feb1de5 100644 --- a/ghcitui.cabal +++ b/ghcitui.cabal @@ -39,34 +39,13 @@ source-repository head executable ghcitui main-is: Main.hs - build-depends: base >= 4.17 && < 5 - , brick >= 2.2 && < 2.4 - , containers >= 0.6.7 && < 0.8 - , errors ^>= 2.3.0 - , file-embed ^>= 0.0.15 + build-depends: base , ghcitui-brick - , ghcitui-core - , microlens ^>= 0.4.13.1 - , microlens-th ^>= 0.4.3.14 , optparse-applicative ^>= 0.18.1.0 - , safe ^>= 0.3.19 - , text ^>= 2.0.2 - , text-zipper ^>= 0.13 - , vector ^>= 0.13.1.0 - , vty >= 5.38 && < 6.1 - , word-wrap ^>= 0.5 + , ghcitui + , text hs-source-dirs: app - other-modules: BrickUI - , AppConfig - , AppInterpState - , AppState - , AppTopLevel - , DrawSourceViewer - , Events - , HelpText - -- Cabal autogen module for package version info. - , Paths_ghcitui - , SplashTextEmbed + other-modules: Paths_ghcitui autogen-modules: Paths_ghcitui ghc-options: -rtsopts -threaded @@ -76,16 +55,11 @@ executable ghcitui -Wpartial-fields -Wredundant-constraints default-language: Haskell2010 - default-extensions: DuplicateRecordFields - LambdaCase - MonoLocalBinds - NamedFieldPuns - OverloadedRecordDot + default-extensions: MonoLocalBinds OverloadedStrings RecordWildCards - TupleSections -library ghcitui-core +library hs-source-dirs: lib/ghcitui-core build-depends: base >= 4.17 && < 5 , array ^>= 0.5.4.0 @@ -125,28 +99,49 @@ library ghcitui-brick , brick >= 2.2 && < 2.4 , containers >= 0.6.7 && < 0.8 , errors ^>= 2.3.0 - , ghcitui-core + , file-embed ^>= 0.0.15 + , ghcitui , microlens ^>= 0.4.13.1 , microlens-th ^>= 0.4.3.14 + , safe ^>= 0.3.19 , text ^>= 2.0.2 + , text-zipper ^>= 0.13 , vector ^>= 0.13.1.0 - exposed-modules: Ghcitui.Brick.SourceWindow + , vty >= 5.38 && < 6.1 + , word-wrap ^>= 0.5 + exposed-modules: Ghcitui.Brick + other-modules: Ghcitui.Brick.AppConfig + , Ghcitui.Brick.AppInterpState + , Ghcitui.Brick.AppState + , Ghcitui.Brick.AppTopLevel + , Ghcitui.Brick.BrickUI + , Ghcitui.Brick.DrawSourceViewer + , Ghcitui.Brick.Events + , Ghcitui.Brick.HelpText + , Ghcitui.Brick.SourceWindow + , Ghcitui.Brick.SplashTextEmbed ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wpartial-fields -Wredundant-constraints default-language: Haskell2010 - default-extensions: OverloadedStrings + default-extensions: DuplicateRecordFields + LambdaCase MonoLocalBinds NamedFieldPuns + OverloadedRecordDot + OverloadedStrings + RecordWildCards + TupleSections + test-suite spec hs-source-dirs: test main-is: Spec.hs type: exitcode-stdio-1.0 build-depends: base >= 4.17 && < 5 - , ghcitui-core + , ghcitui , hspec ^>= 2.11.5 other-modules: LocSpec , UtilSpec diff --git a/lib/ghcitui-brick/Ghcitui/Brick.hs b/lib/ghcitui-brick/Ghcitui/Brick.hs new file mode 100644 index 0000000..5f6fbaa --- /dev/null +++ b/lib/ghcitui-brick/Ghcitui/Brick.hs @@ -0,0 +1,10 @@ +module Ghcitui.Brick + ( -- * Configuration settings for the BrickUI + module Ghcitui.Brick.AppConfig + + -- * Display BrickUI + , module Ghcitui.Brick.BrickUI + ) where + +import Ghcitui.Brick.AppConfig +import Ghcitui.Brick.BrickUI diff --git a/app/AppConfig.hs b/lib/ghcitui-brick/Ghcitui/Brick/AppConfig.hs similarity index 89% rename from app/AppConfig.hs rename to lib/ghcitui-brick/Ghcitui/Brick/AppConfig.hs index ae48021..e7ec5b9 100644 --- a/app/AppConfig.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/AppConfig.hs @@ -1,13 +1,19 @@ {-# LANGUAGE OverloadedStrings #-} -module AppConfig (AppConfig (..), defaultConfig, loadStartupSplash, userConfigDir) where +module Ghcitui.Brick.AppConfig + ( AppConfig (..) + , defaultConfig + , loadStartupSplash + , userConfigDir + ) +where import Data.Maybe (fromMaybe) import Data.String (IsString) import qualified Data.Text as T import System.Environment (lookupEnv) -import qualified SplashTextEmbed +import qualified Ghcitui.Brick.SplashTextEmbed as SplashTextEmbed userConfigDir :: IO FilePath userConfigDir = fromMaybe (error errorMsg) <$> result diff --git a/app/AppInterpState.hs b/lib/ghcitui-brick/Ghcitui/Brick/AppInterpState.hs similarity index 97% rename from app/AppInterpState.hs rename to lib/ghcitui-brick/Ghcitui/Brick/AppInterpState.hs index 2635e1e..245f91e 100644 --- a/app/AppInterpState.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/AppInterpState.hs @@ -1,4 +1,6 @@ -module AppInterpState +{-# LANGUAGE RecordWildCards #-} + +module Ghcitui.Brick.AppInterpState ( AppInterpState (_liveEditor, _viewLock, _commandBuffer, historyPos) , commandBuffer , emptyAppInterpState diff --git a/app/AppState.hs b/lib/ghcitui-brick/Ghcitui/Brick/AppState.hs similarity index 97% rename from app/AppState.hs rename to lib/ghcitui-brick/Ghcitui/Brick/AppState.hs index 0647194..0d3f9ad 100644 --- a/app/AppState.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/AppState.hs @@ -1,6 +1,6 @@ {-# LANGUAGE NamedFieldPuns #-} -module AppState +module Ghcitui.Brick.AppState ( ActiveWindow (..) , AppConfig (..) , AppState (..) @@ -41,9 +41,10 @@ import qualified Data.Vector as Vec import Lens.Micro ((^.)) import qualified Lens.Micro as Lens -import AppConfig (AppConfig (..), loadStartupSplash) -import qualified AppInterpState as AIS -import AppTopLevel (AppName (..)) +import Ghcitui.Brick.AppConfig (AppConfig (..)) +import qualified Ghcitui.Brick.AppConfig as AppConfig +import qualified Ghcitui.Brick.AppInterpState as AIS +import Ghcitui.Brick.AppTopLevel (AppName (..)) import qualified Ghcitui.Brick.SourceWindow as SourceWindow import Ghcitui.Ghcid.Daemon (toggleBreakpointLine) @@ -303,7 +304,7 @@ makeInitialState appConfig target cwd = do Daemon.run (Daemon.startup (T.unpack fullCmd) cwd' startupConfig) >>= \case Right iState -> pure iState Left er -> error (show er) - splashContents <- loadStartupSplash appConfig + splashContents <- AppConfig.loadStartupSplash appConfig let selectedFile' = case Loc.moduleFileMapAssocs (Daemon.moduleFileMap interpState) of -- If we just have one file, select that. diff --git a/app/AppTopLevel.hs b/lib/ghcitui-brick/Ghcitui/Brick/AppTopLevel.hs similarity index 85% rename from app/AppTopLevel.hs rename to lib/ghcitui-brick/Ghcitui/Brick/AppTopLevel.hs index 2a4e677..4f04087 100644 --- a/app/AppTopLevel.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/AppTopLevel.hs @@ -1,4 +1,4 @@ -module AppTopLevel (AppName (..)) where +module Ghcitui.Brick.AppTopLevel (AppName (..)) where -- | Unique identifiers for components of the App. data AppName diff --git a/app/BrickUI.hs b/lib/ghcitui-brick/Ghcitui/Brick/BrickUI.hs similarity index 96% rename from app/BrickUI.hs rename to lib/ghcitui-brick/Ghcitui/Brick/BrickUI.hs index 9d2d7c6..ed609cc 100644 --- a/app/BrickUI.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/BrickUI.hs @@ -1,6 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} -module BrickUI +module Ghcitui.Brick.BrickUI ( launchBrick , AppState (..) ) where @@ -18,25 +18,25 @@ import qualified Graphics.Vty as V import Lens.Micro ((&), (^.)) import qualified Text.Wrap as Wrap -import qualified AppConfig -import qualified AppInterpState as AIS -import AppState +import qualified Ghcitui.Brick.AppConfig as AppConfig +import qualified Ghcitui.Brick.AppInterpState as AIS +import Ghcitui.Brick.AppState ( ActiveWindow (..) , AppState (..) , appInterpState , liveEditor , makeInitialState ) -import qualified AppState -import AppTopLevel (AppName (..)) -import qualified DrawSourceViewer -import qualified Events +import qualified Ghcitui.Brick.AppState as AppState +import Ghcitui.Brick.AppTopLevel (AppName (..)) +import qualified Ghcitui.Brick.DrawSourceViewer as DrawSourceViewer +import qualified Ghcitui.Brick.Events as Events +import qualified Ghcitui.Brick.HelpText as HelpText import qualified Ghcitui.Brick.SourceWindow as SourceWindow import qualified Ghcitui.Ghcid.Daemon as Daemon import qualified Ghcitui.Loc as Loc import qualified Ghcitui.NameBinding as NameBinding import qualified Ghcitui.Util as Util -import qualified HelpText -- | Alias for 'AppState AppName' convenience. type AppS = AppState AppName diff --git a/app/DrawSourceViewer.hs b/lib/ghcitui-brick/Ghcitui/Brick/DrawSourceViewer.hs similarity index 97% rename from app/DrawSourceViewer.hs rename to lib/ghcitui-brick/Ghcitui/Brick/DrawSourceViewer.hs index b62b861..3c9cbee 100644 --- a/app/DrawSourceViewer.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/DrawSourceViewer.hs @@ -1,6 +1,6 @@ {-# LANGUAGE NamedFieldPuns #-} -module DrawSourceViewer (drawSourceViewer) where +module Ghcitui.Brick.DrawSourceViewer (drawSourceViewer) where import qualified Brick as B import qualified Brick.Widgets.Center as B @@ -13,9 +13,9 @@ import qualified Data.Vector as Vec import qualified Graphics.Vty as V import Lens.Micro ((^.)) -import AppState (AppState) -import qualified AppState -import AppTopLevel (AppName (..)) +import Ghcitui.Brick.AppState (AppState) +import qualified Ghcitui.Brick.AppState as AppState +import Ghcitui.Brick.AppTopLevel (AppName (..)) import qualified Ghcitui.Brick.SourceWindow as SourceWindow import qualified Ghcitui.Ghcid.Daemon as Daemon import qualified Ghcitui.Loc as Loc diff --git a/app/Events.hs b/lib/ghcitui-brick/Ghcitui/Brick/Events.hs similarity index 94% rename from app/Events.hs rename to lib/ghcitui-brick/Ghcitui/Brick/Events.hs index 09c1cee..3251316 100644 --- a/app/Events.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/Events.hs @@ -1,7 +1,7 @@ {-# LANGUAGE BlockArguments #-} {-# LANGUAGE NamedFieldPuns #-} -module Events (handleEvent, handleCursorPosition) where +module Ghcitui.Brick.Events (handleEvent, handleCursorPosition) where import qualified Brick.Main as B import qualified Brick.Types as B @@ -14,9 +14,9 @@ import qualified Graphics.Vty as V import Lens.Micro ((^.)) import qualified Lens.Micro as Lens -import qualified AppInterpState as AIS -import AppState -import AppTopLevel +import qualified Ghcitui.Brick.AppInterpState as AIS +import Ghcitui.Brick.AppState as AppState +import Ghcitui.Brick.AppTopLevel ( AppName (..) ) import qualified Ghcitui.Brick.SourceWindow as SourceWindow @@ -32,11 +32,11 @@ handleEvent ev = do updatedSourceWindow <- SourceWindow.updateSrcWindowEnd (appState ^. AppState.sourceWindow) let appStateUpdated = Lens.set AppState.sourceWindow updatedSourceWindow appState let handler = case appStateUpdated.activeWindow of - ActiveCodeViewport -> handleSrcWindowEvent - ActiveLiveInterpreter -> handleInterpreterEvent - ActiveInfoWindow -> handleInfoEvent - ActiveDialogQuit -> handleDialogQuit - ActiveDialogHelp -> handleDialogHelp + AppState.ActiveCodeViewport -> handleSrcWindowEvent + AppState.ActiveLiveInterpreter -> handleInterpreterEvent + AppState.ActiveInfoWindow -> handleInfoEvent + AppState.ActiveDialogQuit -> handleDialogQuit + AppState.ActiveDialogHelp -> handleDialogHelp handler ev -- ------------------------------------------------------------------------------------------------- @@ -61,11 +61,11 @@ handleInfoEvent ev = do invalidateLineCache Nothing -> pure () | key == V.KEsc || key == V.KChar 'C' -> do - B.put appState{activeWindow = ActiveCodeViewport} + B.put appState{activeWindow = AppState.ActiveCodeViewport} B.VtyEvent (V.EvKey (V.KChar 'x') [V.MCtrl]) -> do - B.put appState{activeWindow = ActiveLiveInterpreter} + B.put appState{activeWindow = AppState.ActiveLiveInterpreter} B.VtyEvent (V.EvKey (V.KChar '?') _) -> do - B.put appState{activeWindow = ActiveDialogHelp} + B.put appState{activeWindow = AppState.ActiveDialogHelp} -- Resizing B.VtyEvent (V.EvKey (V.KChar '-') []) -> do @@ -270,9 +270,9 @@ handleSrcWindowEvent (B.VtyEvent (V.EvKey key ms)) B.put . toggleActiveLineInterpreter =<< B.get | key == V.KChar 'M' = do appState <- B.get - B.put appState{activeWindow = ActiveInfoWindow} + B.put appState{activeWindow = AppState.ActiveInfoWindow} B.invalidateCacheEntry ModulesViewport - | key == V.KChar '?' = B.modify (\state -> state{activeWindow = ActiveDialogHelp}) + | key == V.KChar '?' = B.modify (\state -> state{activeWindow = AppState.ActiveDialogHelp}) handleSrcWindowEvent _ = pure () moveSelectedLineby :: Int -> B.EventM AppName (AppState AppName) () @@ -298,7 +298,7 @@ scrollPage dir = do -- | Open up the quit dialog. See 'quit' for the actual quitting. confirmQuit :: B.EventM AppName (AppState AppName) () -confirmQuit = B.put . (\s -> s{activeWindow = ActiveDialogQuit}) =<< B.get +confirmQuit = B.put . (\s -> s{activeWindow = AppState.ActiveDialogQuit}) =<< B.get invalidateCachedLine :: Int -> B.EventM AppName s () invalidateCachedLine lineno = B.invalidateCacheEntry (SourceWindowLine lineno) @@ -376,7 +376,7 @@ handleCursorPosition -> Maybe (B.CursorLocation AppName) -- ^ The chosen cursor location if any. handleCursorPosition s ls = - if s.activeWindow == ActiveLiveInterpreter + if s.activeWindow == AppState.ActiveLiveInterpreter then -- If we're in the interpreter window, show the cursor. B.showCursorNamed widgetName ls else -- No cursor @@ -413,7 +413,7 @@ handleDialogQuit ev = do case ev of (B.VtyEvent (V.EvKey key _)) | key == V.KChar 'q' || key == V.KEsc -> do - B.put $ appState{activeWindow = ActiveCodeViewport} + B.put $ appState{activeWindow = AppState.ActiveCodeViewport} | key == V.KEnter -> quit appState _ -> pure () pure () @@ -422,7 +422,7 @@ handleDialogHelp :: B.BrickEvent AppName e -> B.EventM AppName (AppState AppName handleDialogHelp (B.VtyEvent (V.EvKey key _)) | key == V.KChar 'q' || key == V.KEsc || key == V.KEnter = do appState <- B.get - B.put $ appState{activeWindow = ActiveCodeViewport} + B.put $ appState{activeWindow = AppState.ActiveCodeViewport} | key == V.KPageDown = B.vScrollPage scroller B.Down | key == V.KPageUp = B.vScrollPage scroller B.Up | key == V.KDown = B.vScrollBy scroller 1 diff --git a/app/HelpText.hs b/lib/ghcitui-brick/Ghcitui/Brick/HelpText.hs similarity index 83% rename from app/HelpText.hs rename to lib/ghcitui-brick/Ghcitui/Brick/HelpText.hs index 1b2b6cc..a67496e 100644 --- a/app/HelpText.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/HelpText.hs @@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell #-} -module HelpText (helpText) where +module Ghcitui.Brick.HelpText (helpText) where import Data.String (IsString) diff --git a/app/SplashTextEmbed.hs b/lib/ghcitui-brick/Ghcitui/Brick/SplashTextEmbed.hs similarity index 81% rename from app/SplashTextEmbed.hs rename to lib/ghcitui-brick/Ghcitui/Brick/SplashTextEmbed.hs index 816419a..a837d12 100644 --- a/app/SplashTextEmbed.hs +++ b/lib/ghcitui-brick/Ghcitui/Brick/SplashTextEmbed.hs @@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell #-} -module SplashTextEmbed (splashText) where +module Ghcitui.Brick.SplashTextEmbed (splashText) where import Data.String (IsString)