termonad 0.2.1.0 → 1.0.0.0
raw patch · 26 files changed
+2883/−1399 lines, 26 filesdep +adjunctionsdep +containersdep +distributivedep ~basedep ~haskell-gi-basenew-component:exe:termonad-example-colour-extensionnew-component:exe:termonad-readmePVP ok
version bump matches the API change (PVP)
Dependencies added: adjunctions, containers, distributive, focuslist, genvalidity-containers, genvalidity-hspec, markdown-unlit, mono-traversable, singletons, tasty-hspec
Dependency ranges changed: base, haskell-gi-base
API changes (from Hackage documentation)
- Termonad.App: exitWithConfirmation :: TMState -> IO ()
- Termonad.App: exitWithConfirmationDialog :: TMState -> IO ResponseType
- Termonad.App: quit :: TMState -> IO ()
- Termonad.Config: [cursorColor] :: TMConfig -> !(Colour Double)
- Termonad.Config: instance GHC.Classes.Eq Termonad.Config.FontConfig
- Termonad.Config: instance GHC.Classes.Eq Termonad.Config.ShowScrollbar
- Termonad.Config: instance GHC.Classes.Eq Termonad.Config.TMConfig
- Termonad.Config: instance GHC.Show.Show Termonad.Config.FontConfig
- Termonad.Config: instance GHC.Show.Show Termonad.Config.ShowScrollbar
- Termonad.Config: instance GHC.Show.Show Termonad.Config.TMConfig
- Termonad.Config: lensCursorColor :: Lens' TMConfig (Colour Double)
- Termonad.Config: lensFontConfig :: Lens' TMConfig FontConfig
- Termonad.Config: lensFontFamily :: Lens' FontConfig Text
- Termonad.Config: lensFontSize :: Lens' FontConfig Int
- Termonad.Config: lensScrollbackLen :: Lens' TMConfig Integer
- Termonad.Config: lensShowScrollbar :: Lens' TMConfig ShowScrollbar
- Termonad.FocusList: Focus :: {-# UNPACK #-} !Int -> Focus
- Termonad.FocusList: FocusList :: !Focus -> {-# UNPACK #-} !Int -> !(IntMap a) -> FocusList a
- Termonad.FocusList: NoFocus :: Focus
- Termonad.FocusList: [focusListFocus] :: FocusList a -> !Focus
- Termonad.FocusList: [focusListLen] :: FocusList a -> {-# UNPACK #-} !Int
- Termonad.FocusList: [focusList] :: FocusList a -> !(IntMap a)
- Termonad.FocusList: _Focus :: Prism' Focus Int
- Termonad.FocusList: _NoFocus :: Prism' Focus ()
- Termonad.FocusList: appendFL :: FocusList a -> a -> FocusList a
- Termonad.FocusList: appendSetFocusFL :: FocusList a -> a -> FocusList a
- Termonad.FocusList: data Focus
- Termonad.FocusList: data FocusList a
- Termonad.FocusList: debugFL :: Show a => FocusList a -> String
- Termonad.FocusList: deleteFL :: forall a. (Eq a) => a -> FocusList a -> FocusList a
- Termonad.FocusList: emptyFL :: FocusList a
- Termonad.FocusList: findFL :: (Int -> a -> Bool) -> FocusList a -> Maybe (Int, a)
- Termonad.FocusList: flFromList :: Focus -> [a] -> Maybe (FocusList a)
- Termonad.FocusList: focusItemGetter :: Getter (FocusList a) (Maybe a)
- Termonad.FocusList: foldFocus :: b -> (Int -> b) -> Focus -> b
- Termonad.FocusList: getFLFocusItem :: FocusList a -> Maybe a
- Termonad.FocusList: hasFocus :: Focus -> Bool
- Termonad.FocusList: indexOfFL :: Eq a => a -> FocusList a -> Maybe Int
- Termonad.FocusList: insertFL :: Int -> a -> FocusList a -> Maybe (FocusList a)
- Termonad.FocusList: instance Data.Foldable.Foldable Termonad.FocusList.FocusList
- Termonad.FocusList: instance Data.MonoTraversable.MonoFoldable (Termonad.FocusList.FocusList a)
- Termonad.FocusList: instance Data.MonoTraversable.MonoFunctor (Termonad.FocusList.FocusList a)
- Termonad.FocusList: instance Data.MonoTraversable.MonoTraversable (Termonad.FocusList.FocusList a)
- Termonad.FocusList: instance Data.Traversable.Traversable Termonad.FocusList.FocusList
- Termonad.FocusList: instance GHC.Base.Functor Termonad.FocusList.FocusList
- Termonad.FocusList: instance GHC.Classes.Eq Termonad.FocusList.Focus
- Termonad.FocusList: instance GHC.Classes.Eq a => GHC.Classes.Eq (Termonad.FocusList.FocusList a)
- Termonad.FocusList: instance GHC.Classes.Ord Termonad.FocusList.Focus
- Termonad.FocusList: instance GHC.Generics.Generic (Termonad.FocusList.FocusList a)
- Termonad.FocusList: instance GHC.Generics.Generic Termonad.FocusList.Focus
- Termonad.FocusList: instance GHC.Read.Read Termonad.FocusList.Focus
- Termonad.FocusList: instance GHC.Show.Show Termonad.FocusList.Focus
- Termonad.FocusList: instance GHC.Show.Show a => GHC.Show.Show (Termonad.FocusList.FocusList a)
- Termonad.FocusList: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Termonad.FocusList.FocusList a)
- Termonad.FocusList: instance Test.QuickCheck.Arbitrary.Arbitrary1 Termonad.FocusList.FocusList
- Termonad.FocusList: instance Test.QuickCheck.Arbitrary.CoArbitrary Termonad.FocusList.Focus
- Termonad.FocusList: instance Test.QuickCheck.Arbitrary.CoArbitrary a => Test.QuickCheck.Arbitrary.CoArbitrary (Termonad.FocusList.FocusList a)
- Termonad.FocusList: invariantFL :: FocusList a -> Bool
- Termonad.FocusList: isEmptyFL :: FocusList a -> Bool
- Termonad.FocusList: lensFocusList :: forall a_a1j6g a_a1pE2. Lens (FocusList a_a1j6g) (FocusList a_a1pE2) (IntMap a_a1j6g) (IntMap a_a1pE2)
- Termonad.FocusList: lensFocusListAt :: Int -> Lens' (FocusList a) (Maybe a)
- Termonad.FocusList: lensFocusListFocus :: forall a_a1j6g. Lens' (FocusList a_a1j6g) Focus
- Termonad.FocusList: lensFocusListLen :: forall a_a1j6g. Lens' (FocusList a_a1j6g) Int
- Termonad.FocusList: lookupFL :: Int -> FocusList a -> Maybe a
- Termonad.FocusList: moveFromToFL :: Show a => Int -> Int -> FocusList a -> Maybe (FocusList a)
- Termonad.FocusList: prependFL :: a -> FocusList a -> FocusList a
- Termonad.FocusList: removeFL :: Int -> FocusList a -> Maybe (FocusList a)
- Termonad.FocusList: setFocusFL :: Int -> FocusList a -> Maybe (FocusList a)
- Termonad.FocusList: singletonFL :: a -> FocusList a
- Termonad.FocusList: unsafeFLFromList :: Focus -> [a] -> FocusList a
- Termonad.FocusList: unsafeGetFLFocus :: FocusList a -> Int
- Termonad.FocusList: unsafeGetFLFocusItem :: FocusList a -> a
- Termonad.FocusList: unsafeGetFocus :: Focus -> Int
- Termonad.FocusList: unsafeInsertNewFL :: Int -> a -> FocusList a -> FocusList a
- Termonad.FocusList: unsafeLookup :: Int -> IntMap a -> a
- Termonad.FocusList: unsafeRemove :: Int -> FocusList a -> FocusList a
- Termonad.FocusList: unsafeShiftDownFrom :: forall a. Int -> FocusList a -> FocusList a
- Termonad.FocusList: unsafeShiftUpFrom :: forall a. Int -> FocusList a -> FocusList a
- Termonad.FocusList: updateFocusFL :: Int -> FocusList a -> Maybe (a, FocusList a)
- Termonad.Term: getCursorColor :: TMConfig -> IO RGBA
- Termonad.Types: UserDidNotRequestExit :: UserRequestedExit
- Termonad.Types: UserRequestedExit :: UserRequestedExit
- Termonad.Types: [tmStateUserReqExit] :: TMState' -> !UserRequestedExit
- Termonad.Types: data UserRequestedExit
- Termonad.Types: getUserRequestedExit :: TMState -> IO UserRequestedExit
- Termonad.Types: instance GHC.Classes.Eq Termonad.Types.UserRequestedExit
- Termonad.Types: instance GHC.Show.Show Termonad.Types.UserRequestedExit
- Termonad.Types: lensPid :: Lens' TMTerm Int
- Termonad.Types: lensTMNotebook :: Lens' TMNotebook Notebook
- Termonad.Types: lensTMNotebookTabLabel :: Lens' TMNotebookTab Label
- Termonad.Types: lensTMNotebookTabTerm :: Lens' TMNotebookTab TMTerm
- Termonad.Types: lensTMNotebookTabTermContainer :: Lens' TMNotebookTab ScrolledWindow
- Termonad.Types: lensTMNotebookTabs :: Lens' TMNotebook (FocusList TMNotebookTab)
- Termonad.Types: lensTMStateApp :: Lens' TMState' Application
- Termonad.Types: lensTMStateAppWin :: Lens' TMState' ApplicationWindow
- Termonad.Types: lensTMStateConfig :: Lens' TMState' TMConfig
- Termonad.Types: lensTMStateFontDesc :: Lens' TMState' FontDescription
- Termonad.Types: lensTMStateNotebook :: Lens' TMState' TMNotebook
- Termonad.Types: lensTMStateUserReqExit :: Lens' TMState' UserRequestedExit
- Termonad.Types: lensTerm :: Lens' TMTerm Terminal
- Termonad.Types: lensUnique :: Lens' TMTerm Unique
- Termonad.Types: pTraceShowMTMState :: TMState -> IO ()
- Termonad.Types: setUserRequestedExit :: TMState -> IO ()
+ Termonad: start :: TMConfig -> IO ()
+ Termonad.App: askShouldExit :: TMState -> IO ResponseType
+ Termonad.App: forceQuit :: TMState -> IO ()
+ Termonad.Config: AnotherCursorBlinkMode :: Int -> CursorBlinkMode
+ Termonad.Config: ConfigHooks :: TMState -> Terminal -> IO () -> ConfigHooks
+ Termonad.Config: ConfigOptions :: !FontConfig -> !ShowScrollbar -> !Integer -> !Bool -> !Text -> !Bool -> !ShowTabBar -> !CursorBlinkMode -> ConfigOptions
+ Termonad.Config: CursorBlinkModeOff :: CursorBlinkMode
+ Termonad.Config: CursorBlinkModeOn :: CursorBlinkMode
+ Termonad.Config: CursorBlinkModeSystem :: CursorBlinkMode
+ Termonad.Config: FontSizePoints :: Int -> FontSize
+ Termonad.Config: FontSizeUnits :: Double -> FontSize
+ Termonad.Config: Set :: !a -> Option a
+ Termonad.Config: ShowTabBarAlways :: ShowTabBar
+ Termonad.Config: ShowTabBarIfNeeded :: ShowTabBar
+ Termonad.Config: ShowTabBarNever :: ShowTabBar
+ Termonad.Config: Unset :: Option a
+ Termonad.Config: [confirmExit] :: ConfigOptions -> !Bool
+ Termonad.Config: [createTermHook] :: ConfigHooks -> TMState -> Terminal -> IO ()
+ Termonad.Config: [cursorBlinkMode] :: ConfigOptions -> !CursorBlinkMode
+ Termonad.Config: [hooks] :: TMConfig -> !ConfigHooks
+ Termonad.Config: [options] :: TMConfig -> !ConfigOptions
+ Termonad.Config: [showMenu] :: ConfigOptions -> !Bool
+ Termonad.Config: [showTabBar] :: ConfigOptions -> !ShowTabBar
+ Termonad.Config: [wordCharExceptions] :: ConfigOptions -> !Text
+ Termonad.Config: data ConfigHooks
+ Termonad.Config: data ConfigOptions
+ Termonad.Config: data CursorBlinkMode
+ Termonad.Config: data FontSize
+ Termonad.Config: data Option a
+ Termonad.Config: data ShowTabBar
+ Termonad.Config: defaultConfigHooks :: ConfigHooks
+ Termonad.Config: defaultConfigOptions :: ConfigOptions
+ Termonad.Config: defaultFontSize :: FontSize
+ Termonad.Config.Colour: BasicPalette :: !(Vec N8 c) -> Palette c
+ Termonad.Config.Colour: ColourConfig :: !(Option c) -> !(Option c) -> !c -> !c -> !(Palette c) -> ColourConfig c
+ Termonad.Config.Colour: ColourCubePalette :: !(Vec N8 c) -> !(Vec N8 c) -> !(Matrix '[N6, N6, N6] c) -> Palette c
+ Termonad.Config.Colour: ColourExtension :: MVar (ColourConfig (Colour Double)) -> TMState -> Terminal -> IO () -> ColourExtension
+ Termonad.Config.Colour: ExtendedPalette :: !(Vec N8 c) -> !(Vec N8 c) -> Palette c
+ Termonad.Config.Colour: FullPalette :: !(Vec N8 c) -> !(Vec N8 c) -> !(Matrix '[N6, N6, N6] c) -> !(Vec N24 c) -> Palette c
+ Termonad.Config.Colour: NoPalette :: Palette c
+ Termonad.Config.Colour: [backgroundColour] :: ColourConfig c -> !c
+ Termonad.Config.Colour: [colourExtConf] :: ColourExtension -> MVar (ColourConfig (Colour Double))
+ Termonad.Config.Colour: [colourExtCreateTermHook] :: ColourExtension -> TMState -> Terminal -> IO ()
+ Termonad.Config.Colour: [cursorBgColour] :: ColourConfig c -> !(Option c)
+ Termonad.Config.Colour: [cursorFgColour] :: ColourConfig c -> !(Option c)
+ Termonad.Config.Colour: [foregroundColour] :: ColourConfig c -> !c
+ Termonad.Config.Colour: [palette] :: ColourConfig c -> !(Palette c)
+ Termonad.Config.Colour: addColourConfig :: TMConfig -> ColourConfig (Colour Double) -> IO TMConfig
+ Termonad.Config.Colour: addColourExtension :: TMConfig -> ColourExtension -> TMConfig
+ Termonad.Config.Colour: addColourHook :: (TMState -> Terminal -> IO ()) -> (TMState -> Terminal -> IO ()) -> TMState -> Terminal -> IO ()
+ Termonad.Config.Colour: colourHook :: MVar (ColourConfig (Colour Double)) -> TMState -> Terminal -> IO ()
+ Termonad.Config.Colour: coloursFromBits :: forall b. (Ord b, Floating b) => Word8 -> Word8 -> Vec N8 (Colour b)
+ Termonad.Config.Colour: createColourExtension :: ColourConfig (Colour Double) -> IO ColourExtension
+ Termonad.Config.Colour: createDefColourExtension :: IO ColourExtension
+ Termonad.Config.Colour: cube :: forall b. Fractional b => Colour b -> Vec N3 (Colour b) -> Matrix '[N6, N6, N6] (Colour b)
+ Termonad.Config.Colour: data Colour a
+ Termonad.Config.Colour: data ColourConfig c
+ Termonad.Config.Colour: data ColourExtension
+ Termonad.Config.Colour: data Palette c
+ Termonad.Config.Colour: defaultColourConfig :: ColourConfig (Colour Double)
+ Termonad.Config.Colour: defaultColourCube :: (Ord b, Floating b) => Matrix '[N6, N6, N6] (Colour b)
+ Termonad.Config.Colour: defaultGreyscale :: (Ord b, Floating b) => Vec N24 (Colour b)
+ Termonad.Config.Colour: defaultLightColours :: (Ord b, Floating b) => Vec N8 (Colour b)
+ Termonad.Config.Colour: defaultStandardColours :: (Ord b, Floating b) => Vec N8 (Colour b)
+ Termonad.Config.Colour: instance Data.Foldable.Foldable Termonad.Config.Colour.Palette
+ Termonad.Config.Colour: instance GHC.Base.Functor Termonad.Config.Colour.ColourConfig
+ Termonad.Config.Colour: instance GHC.Base.Functor Termonad.Config.Colour.Palette
+ Termonad.Config.Colour: instance GHC.Classes.Eq c => GHC.Classes.Eq (Termonad.Config.Colour.ColourConfig c)
+ Termonad.Config.Colour: instance GHC.Classes.Eq c => GHC.Classes.Eq (Termonad.Config.Colour.Palette c)
+ Termonad.Config.Colour: instance GHC.Show.Show c => GHC.Show.Show (Termonad.Config.Colour.ColourConfig c)
+ Termonad.Config.Colour: instance GHC.Show.Show c => GHC.Show.Show (Termonad.Config.Colour.Palette c)
+ Termonad.Config.Colour: lensBackgroundColour :: forall c_a2csI. Lens' (ColourConfig c_a2csI) c_a2csI
+ Termonad.Config.Colour: lensCursorBgColour :: forall c_a2csI. Lens' (ColourConfig c_a2csI) (Option c_a2csI)
+ Termonad.Config.Colour: lensCursorFgColour :: forall c_a2csI. Lens' (ColourConfig c_a2csI) (Option c_a2csI)
+ Termonad.Config.Colour: lensForegroundColour :: forall c_a2csI. Lens' (ColourConfig c_a2csI) c_a2csI
+ Termonad.Config.Colour: lensPalette :: forall c_a2csI. Lens' (ColourConfig c_a2csI) (Palette c_a2csI)
+ Termonad.Config.Colour: paletteToList :: Palette c -> [c]
+ Termonad.Config.Colour: sRGB24 :: (Ord b, Floating b) => Word8 -> Word8 -> Word8 -> Colour b
+ Termonad.Config.Colour: sRGB24show :: (RealFrac b, Floating b) => Colour b -> String
+ Termonad.Config.Colour: showColourCube :: Matrix '[N6, N6, N6] (Colour Double) -> String
+ Termonad.Config.Colour: showColourVec :: forall n. Vec n (Colour Double) -> [String]
+ Termonad.Config.Vec: Abs_6989586621679401487Sym0KindInference :: Abs_6989586621679401487Sym0
+ Termonad.Config.Vec: AddPeanoSym0KindInference :: AddPeanoSym0
+ Termonad.Config.Vec: AddPeanoSym1KindInference :: AddPeanoSym1
+ Termonad.Config.Vec: Compare_6989586621679400935Sym0KindInference :: Compare_6989586621679400935Sym0
+ Termonad.Config.Vec: Compare_6989586621679400935Sym1KindInference :: Compare_6989586621679400935Sym1
+ Termonad.Config.Vec: FromInteger_6989586621679401522Sym0KindInference :: FromInteger_6989586621679401522Sym0
+ Termonad.Config.Vec: Let6989586621679401507Scrutinee_6989586621679389242Sym0KindInference :: Let6989586621679401507Scrutinee_6989586621679389242Sym0 l_a1DU1
+ Termonad.Config.Vec: Let6989586621679401513Scrutinee_6989586621679389244Sym0KindInference :: Let6989586621679401513Scrutinee_6989586621679389244Sym0 l_a1DU7
+ Termonad.Config.Vec: Matrix :: MatrixTF ns a -> Matrix ns a
+ Termonad.Config.Vec: MatrixTFSym0KindInference :: MatrixTFSym0
+ Termonad.Config.Vec: MatrixTFSym1KindInference :: MatrixTFSym1
+ Termonad.Config.Vec: MultPeanoSym0KindInference :: MultPeanoSym0
+ Termonad.Config.Vec: MultPeanoSym1KindInference :: MultPeanoSym1
+ Termonad.Config.Vec: S :: Peano -> Peano
+ Termonad.Config.Vec: SSym0KindInference :: SSym0
+ Termonad.Config.Vec: ShowsPrec_6989586621679401357Sym0KindInference :: ShowsPrec_6989586621679401357Sym0
+ Termonad.Config.Vec: ShowsPrec_6989586621679401357Sym1KindInference :: ShowsPrec_6989586621679401357Sym1
+ Termonad.Config.Vec: ShowsPrec_6989586621679401357Sym2KindInference :: ShowsPrec_6989586621679401357Sym2
+ Termonad.Config.Vec: Signum_6989586621679401497Sym0KindInference :: Signum_6989586621679401497Sym0
+ Termonad.Config.Vec: SubtractPeanoSym0KindInference :: SubtractPeanoSym0
+ Termonad.Config.Vec: SubtractPeanoSym1KindInference :: SubtractPeanoSym1
+ Termonad.Config.Vec: TFHelper_6989586621679401418Sym0KindInference :: TFHelper_6989586621679401418Sym0
+ Termonad.Config.Vec: TFHelper_6989586621679401418Sym1KindInference :: TFHelper_6989586621679401418Sym1
+ Termonad.Config.Vec: TFHelper_6989586621679401444Sym0KindInference :: TFHelper_6989586621679401444Sym0
+ Termonad.Config.Vec: TFHelper_6989586621679401444Sym1KindInference :: TFHelper_6989586621679401444Sym1
+ Termonad.Config.Vec: TFHelper_6989586621679401470Sym0KindInference :: TFHelper_6989586621679401470Sym0
+ Termonad.Config.Vec: TFHelper_6989586621679401470Sym1KindInference :: TFHelper_6989586621679401470Sym1
+ Termonad.Config.Vec: Z :: Peano
+ Termonad.Config.Vec: [:*] :: !a -> !(Vec n a) -> Vec ( 'S n) a
+ Termonad.Config.Vec: [:<] :: forall (f :: k -> Type) (a :: k) (as :: [k]). f a -> HList f as -> HList f (a : as)
+ Termonad.Config.Vec: [EmptyHList] :: HList f '[]
+ Termonad.Config.Vec: [EmptyVec] :: Vec 'Z a
+ Termonad.Config.Vec: [FS] :: forall (n :: Peano). !(Fin n) -> Fin ( 'S n)
+ Termonad.Config.Vec: [FZ] :: forall (n :: Peano). Fin ( 'S n)
+ Termonad.Config.Vec: [IFS] :: forall (n :: Peano) (m :: Peano). !(IFin n m) -> IFin ( 'S n) ( 'S m)
+ Termonad.Config.Vec: [IFZ] :: forall (n :: Peano). IFin ( 'S n) 'Z
+ Termonad.Config.Vec: [unMatrix] :: Matrix ns a -> MatrixTF ns a
+ Termonad.Config.Vec: addPeano :: Peano -> Peano -> Peano
+ Termonad.Config.Vec: apVec :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c
+ Termonad.Config.Vec: compareSingMatrix :: forall (peanos :: [Peano]) (a :: Type) (c :: Type). (a -> a -> c) -> c -> (c -> c -> c) -> Sing peanos -> Matrix peanos a -> Matrix peanos a -> c
+ Termonad.Config.Vec: consMatrix :: Matrix ns a -> Matrix (n : ns) a -> Matrix ( 'S n : ns) a
+ Termonad.Config.Vec: data Abs_6989586621679401487Sym0 (l_a1DTI :: TyFun Peano Peano)
+ Termonad.Config.Vec: data AddPeanoSym0 (l_a1Dsp :: TyFun Peano (TyFun Peano Peano -> Type))
+ Termonad.Config.Vec: data AddPeanoSym1 (l_a1Dsn :: Peano) (l_a1Dsm :: TyFun Peano Peano)
+ Termonad.Config.Vec: data Compare_6989586621679400935Sym0 (l_a1DKS :: TyFun Peano (TyFun Peano Ordering -> Type))
+ Termonad.Config.Vec: data Compare_6989586621679400935Sym1 (l_a1DKQ :: Peano) (l_a1DKP :: TyFun Peano Ordering)
+ Termonad.Config.Vec: data Fin :: Peano -> Type
+ Termonad.Config.Vec: data FromInteger_6989586621679401522Sym0 (l_a1DUh :: TyFun Nat Peano)
+ Termonad.Config.Vec: data HList :: (k -> Type) -> [k] -> Type
+ Termonad.Config.Vec: data IFin :: Peano -> Peano -> Type
+ Termonad.Config.Vec: data Let6989586621679401507Scrutinee_6989586621679389242Sym0 l_a1DU1
+ Termonad.Config.Vec: data Let6989586621679401513Scrutinee_6989586621679389244Sym0 l_a1DU7
+ Termonad.Config.Vec: data MatrixTFSym0 (l :: TyFun [Peano] (Type ~> Type))
+ Termonad.Config.Vec: data MatrixTFSym1 (ns :: [Peano]) (z :: TyFun Type Type)
+ Termonad.Config.Vec: data MultPeanoSym0 (l_a1DsB :: TyFun Peano (TyFun Peano Peano -> Type))
+ Termonad.Config.Vec: data MultPeanoSym1 (l_a1Dsz :: Peano) (l_a1Dsy :: TyFun Peano Peano)
+ Termonad.Config.Vec: data Peano
+ Termonad.Config.Vec: data SSym0 (l_a1Ds6 :: TyFun Peano Peano)
+ Termonad.Config.Vec: data ShowsPrec_6989586621679401357Sym0 (l_a1DRL :: TyFun Nat (TyFun Peano (TyFun Symbol Symbol -> Type) -> Type))
+ Termonad.Config.Vec: data ShowsPrec_6989586621679401357Sym1 (l_a1DRJ :: Nat) (l_a1DRI :: TyFun Peano (TyFun Symbol Symbol -> Type))
+ Termonad.Config.Vec: data ShowsPrec_6989586621679401357Sym2 (l_a1DRF :: Nat) (l_a1DRG :: Peano) (l_a1DRE :: TyFun Symbol Symbol)
+ Termonad.Config.Vec: data Signum_6989586621679401497Sym0 (l_a1DTS :: TyFun Peano Peano)
+ Termonad.Config.Vec: data SubtractPeanoSym0 (l_a1Dsd :: TyFun Peano (TyFun Peano Peano -> Type))
+ Termonad.Config.Vec: data SubtractPeanoSym1 (l_a1Dsb :: Peano) (l_a1Dsa :: TyFun Peano Peano)
+ Termonad.Config.Vec: data TFHelper_6989586621679401418Sym0 (l_a1DSF :: TyFun Peano (TyFun Peano Peano -> Type))
+ Termonad.Config.Vec: data TFHelper_6989586621679401418Sym1 (l_a1DSD :: Peano) (l_a1DSC :: TyFun Peano Peano)
+ Termonad.Config.Vec: data TFHelper_6989586621679401444Sym0 (l_a1DT5 :: TyFun Peano (TyFun Peano Peano -> Type))
+ Termonad.Config.Vec: data TFHelper_6989586621679401444Sym1 (l_a1DT3 :: Peano) (l_a1DT2 :: TyFun Peano Peano)
+ Termonad.Config.Vec: data TFHelper_6989586621679401470Sym0 (l_a1DTv :: TyFun Peano (TyFun Peano Peano -> Type))
+ Termonad.Config.Vec: data TFHelper_6989586621679401470Sym1 (l_a1DTt :: Peano) (l_a1DTs :: TyFun Peano Peano)
+ Termonad.Config.Vec: data Vec (n :: Peano) :: Type -> Type
+ Termonad.Config.Vec: dropVec :: Sing m -> Vec (m + n) a -> Vec n a
+ Termonad.Config.Vec: eqSingMatrix :: forall (peanos :: [Peano]) (a :: Type). Eq a => Sing peanos -> Matrix peanos a -> Matrix peanos a -> Bool
+ Termonad.Config.Vec: fmapSingMatrix :: forall (peanos :: [Peano]) (a :: Type) (b :: Type). Sing peanos -> (a -> b) -> Matrix peanos a -> Matrix peanos b
+ Termonad.Config.Vec: genMatrix :: forall (ns :: [Peano]) (a :: Type). Sing ns -> (HList Fin ns -> a) -> Matrix ns a
+ Termonad.Config.Vec: genMatrix_ :: SingI ns => (HList Fin ns -> a) -> Matrix ns a
+ Termonad.Config.Vec: genVec :: SPeano n -> (Fin n -> a) -> Vec n a
+ Termonad.Config.Vec: genVec_ :: SingI n => (Fin n -> a) -> Vec n a
+ Termonad.Config.Vec: imapMatrix :: forall (ns :: [Peano]) a b. Sing ns -> (HList Fin ns -> a -> b) -> Matrix ns a -> Matrix ns b
+ Termonad.Config.Vec: imapMatrix_ :: SingI ns => (HList Fin ns -> a -> b) -> Matrix ns a -> Matrix ns b
+ Termonad.Config.Vec: imapVec :: forall n a b. (Fin n -> a -> b) -> Vec n a -> Vec n b
+ Termonad.Config.Vec: indexMatrix :: HList Fin ns -> Matrix ns a -> a
+ Termonad.Config.Vec: indexVec :: Fin n -> Vec n a -> a
+ Termonad.Config.Vec: instance Data.Foldable.Foldable (Termonad.Config.Vec.Vec n)
+ Termonad.Config.Vec: instance Data.MonoTraversable.MonoFoldable (Termonad.Config.Vec.Vec n a)
+ Termonad.Config.Vec: instance Data.MonoTraversable.MonoFunctor (Termonad.Config.Vec.Vec n a)
+ Termonad.Config.Vec: instance Data.Singletons.Decide.SDecide Termonad.Config.Vec.Peano => Data.Singletons.Decide.SDecide Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI 'Termonad.Config.Vec.FZ
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI 'Termonad.Config.Vec.IFZ
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI 'Termonad.Config.Vec.Z
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI n => Data.Distributive.Distributive (Termonad.Config.Vec.Vec n)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI n => Data.Functor.Rep.Representable (Termonad.Config.Vec.Vec n)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI n => Data.MonoTraversable.MonoPointed (Termonad.Config.Vec.Vec n a)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI n => Data.Singletons.Internal.SingI ('Termonad.Config.Vec.S n)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI n => GHC.Base.Applicative (Termonad.Config.Vec.Vec n)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI n => GHC.Base.Monad (Termonad.Config.Vec.Vec n)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI ns => Data.Distributive.Distributive (Termonad.Config.Vec.Matrix ns)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI ns => Data.Foldable.Foldable (Termonad.Config.Vec.Matrix ns)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI ns => Data.Functor.Rep.Representable (Termonad.Config.Vec.Matrix ns)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI ns => Data.MonoTraversable.MonoFoldable (Termonad.Config.Vec.Matrix ns a)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI ns => GHC.Base.Applicative (Termonad.Config.Vec.Matrix ns)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI ns => GHC.Base.Functor (Termonad.Config.Vec.Matrix ns)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingI ns => GHC.Base.Monad (Termonad.Config.Vec.Matrix ns)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingKind (Termonad.Config.Vec.Fin n)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingKind (Termonad.Config.Vec.IFin n m)
+ Termonad.Config.Vec: instance Data.Singletons.Internal.SingKind Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Eq.PEq Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Eq.SEq Termonad.Config.Vec.Peano => Data.Singletons.Prelude.Eq.SEq Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Num.PNum Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Num.SNum Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Ord.POrd Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Ord.SOrd Termonad.Config.Vec.Peano => Data.Singletons.Prelude.Ord.SOrd Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Show.PShow Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.Prelude.Show.SShow Termonad.Config.Vec.Peano => Data.Singletons.Prelude.Show.SShow Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.ShowSing.ShowSing Termonad.Config.Vec.Peano => Data.Singletons.ShowSing.ShowSing Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance Data.Singletons.ShowSing.ShowSing Termonad.Config.Vec.Peano => GHC.Show.Show (Data.Singletons.Internal.Sing z)
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.Abs_6989586621679401487Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.AddPeanoSym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.AddPeanoSym1
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.Compare_6989586621679400935Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.Compare_6989586621679400935Sym1
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.FromInteger_6989586621679401522Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.Let6989586621679401507Scrutinee_6989586621679389242Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.Let6989586621679401513Scrutinee_6989586621679389244Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.MultPeanoSym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.MultPeanoSym1
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.SSym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.ShowsPrec_6989586621679401357Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.ShowsPrec_6989586621679401357Sym1
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.ShowsPrec_6989586621679401357Sym2
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.Signum_6989586621679401497Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.SubtractPeanoSym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.SubtractPeanoSym1
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.TFHelper_6989586621679401418Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.TFHelper_6989586621679401418Sym1
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.TFHelper_6989586621679401444Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.TFHelper_6989586621679401444Sym1
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.TFHelper_6989586621679401470Sym0
+ Termonad.Config.Vec: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Termonad.Config.Vec.TFHelper_6989586621679401470Sym1
+ Termonad.Config.Vec: instance GHC.Base.Functor (Termonad.Config.Vec.Vec n)
+ Termonad.Config.Vec: instance GHC.Classes.Eq (Termonad.Config.Vec.Fin n)
+ Termonad.Config.Vec: instance GHC.Classes.Eq (Termonad.Config.Vec.IFin x y)
+ Termonad.Config.Vec: instance GHC.Classes.Eq (Termonad.Config.Vec.MatrixTF ns a) => GHC.Classes.Eq (Termonad.Config.Vec.Matrix ns a)
+ Termonad.Config.Vec: instance GHC.Classes.Eq Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance GHC.Classes.Eq a => GHC.Classes.Eq (Termonad.Config.Vec.Vec n a)
+ Termonad.Config.Vec: instance GHC.Classes.Ord (Termonad.Config.Vec.Fin n)
+ Termonad.Config.Vec: instance GHC.Classes.Ord (Termonad.Config.Vec.IFin x y)
+ Termonad.Config.Vec: instance GHC.Classes.Ord (Termonad.Config.Vec.MatrixTF ns a) => GHC.Classes.Ord (Termonad.Config.Vec.Matrix ns a)
+ Termonad.Config.Vec: instance GHC.Classes.Ord Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance GHC.Classes.Ord a => GHC.Classes.Ord (Termonad.Config.Vec.Vec n a)
+ Termonad.Config.Vec: instance GHC.Num.Num Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance GHC.Num.Num a => GHC.Num.Num (Termonad.Config.Vec.Matrix '[] a)
+ Termonad.Config.Vec: instance GHC.Show.Show (Data.Singletons.Internal.Sing 'Termonad.Config.Vec.FZ)
+ Termonad.Config.Vec: instance GHC.Show.Show (Data.Singletons.Internal.Sing 'Termonad.Config.Vec.IFZ)
+ Termonad.Config.Vec: instance GHC.Show.Show (Termonad.Config.Vec.Fin n)
+ Termonad.Config.Vec: instance GHC.Show.Show (Termonad.Config.Vec.IFin x y)
+ Termonad.Config.Vec: instance GHC.Show.Show (Termonad.Config.Vec.MatrixTF ns a) => GHC.Show.Show (Termonad.Config.Vec.Matrix ns a)
+ Termonad.Config.Vec: instance GHC.Show.Show Termonad.Config.Vec.Peano
+ Termonad.Config.Vec: instance GHC.Show.Show a => GHC.Show.Show (Termonad.Config.Vec.Vec n a)
+ Termonad.Config.Vec: instance forall (n1 :: Termonad.Config.Vec.Peano) (m :: Termonad.Config.Vec.Peano) (n2 :: Termonad.Config.Vec.IFin n1 m). Data.Singletons.Internal.SingI n2 => Data.Singletons.Internal.SingI ('Termonad.Config.Vec.IFS n2)
+ Termonad.Config.Vec: instance forall (n1 :: Termonad.Config.Vec.Peano) (m :: Termonad.Config.Vec.Peano) (n2 :: Termonad.Config.Vec.IFin n1 m). GHC.Show.Show (Data.Singletons.Internal.Sing n2) => GHC.Show.Show (Data.Singletons.Internal.Sing ('Termonad.Config.Vec.IFS n2))
+ Termonad.Config.Vec: instance forall (n1 :: Termonad.Config.Vec.Peano) (n2 :: Termonad.Config.Vec.Fin n1). Data.Singletons.Internal.SingI n2 => Data.Singletons.Internal.SingI ('Termonad.Config.Vec.FS n2)
+ Termonad.Config.Vec: instance forall (n1 :: Termonad.Config.Vec.Peano) (n2 :: Termonad.Config.Vec.Fin n1). GHC.Show.Show (Data.Singletons.Internal.Sing n2) => GHC.Show.Show (Data.Singletons.Internal.Sing ('Termonad.Config.Vec.FS n2))
+ Termonad.Config.Vec: multPeano :: Peano -> Peano -> Peano
+ Termonad.Config.Vec: n0 :: Peano
+ Termonad.Config.Vec: n1 :: Peano
+ Termonad.Config.Vec: n10 :: Peano
+ Termonad.Config.Vec: n2 :: Peano
+ Termonad.Config.Vec: n24 :: Peano
+ Termonad.Config.Vec: n3 :: Peano
+ Termonad.Config.Vec: n4 :: Peano
+ Termonad.Config.Vec: n5 :: Peano
+ Termonad.Config.Vec: n6 :: Peano
+ Termonad.Config.Vec: n7 :: Peano
+ Termonad.Config.Vec: n8 :: Peano
+ Termonad.Config.Vec: n9 :: Peano
+ Termonad.Config.Vec: newtype Matrix ns a
+ Termonad.Config.Vec: onHeadVec :: (a -> a) -> Vec ( 'S n) a -> Vec ( 'S n) a
+ Termonad.Config.Vec: onMatrix :: (Matrix ns a -> Matrix ms b) -> MatrixTF ns a -> MatrixTF ms b
+ Termonad.Config.Vec: onMatrixTF :: (MatrixTF ns a -> MatrixTF ms b) -> Matrix ns a -> Matrix ms b
+ Termonad.Config.Vec: ordSingMatrix :: forall (peanos :: [Peano]) (a :: Type). Ord a => Sing peanos -> Matrix peanos a -> Matrix peanos a -> Ordering
+ Termonad.Config.Vec: replaceVec :: Sing n -> a -> Vec n a
+ Termonad.Config.Vec: replaceVec_ :: SingI n => a -> Vec n a
+ Termonad.Config.Vec: sAddPeano :: forall (t_a1DUr :: Peano) (t_a1DUs :: Peano). Sing t_a1DUr -> Sing t_a1DUs -> Sing (Apply (Apply AddPeanoSym0 t_a1DUr) t_a1DUs :: Peano)
+ Termonad.Config.Vec: sMultPeano :: forall (t_a1DUt :: Peano) (t_a1DUu :: Peano). Sing t_a1DUt -> Sing t_a1DUu -> Sing (Apply (Apply MultPeanoSym0 t_a1DUt) t_a1DUu :: Peano)
+ Termonad.Config.Vec: sN0 :: Sing (N0Sym0 :: Peano)
+ Termonad.Config.Vec: sN1 :: Sing (N1Sym0 :: Peano)
+ Termonad.Config.Vec: sN10 :: Sing (N10Sym0 :: Peano)
+ Termonad.Config.Vec: sN2 :: Sing (N2Sym0 :: Peano)
+ Termonad.Config.Vec: sN24 :: Sing (N24Sym0 :: Peano)
+ Termonad.Config.Vec: sN3 :: Sing (N3Sym0 :: Peano)
+ Termonad.Config.Vec: sN4 :: Sing (N4Sym0 :: Peano)
+ Termonad.Config.Vec: sN5 :: Sing (N5Sym0 :: Peano)
+ Termonad.Config.Vec: sN6 :: Sing (N6Sym0 :: Peano)
+ Termonad.Config.Vec: sN7 :: Sing (N7Sym0 :: Peano)
+ Termonad.Config.Vec: sN8 :: Sing (N8Sym0 :: Peano)
+ Termonad.Config.Vec: sN9 :: Sing (N9Sym0 :: Peano)
+ Termonad.Config.Vec: sSubtractPeano :: forall (t_a1DUp :: Peano) (t_a1DUq :: Peano). Sing t_a1DUp -> Sing t_a1DUq -> Sing (Apply (Apply SubtractPeanoSym0 t_a1DUp) t_a1DUq :: Peano)
+ Termonad.Config.Vec: setAtMatrix :: HList Fin ns -> a -> Matrix ns a -> Matrix ns a
+ Termonad.Config.Vec: setAtVec :: Fin n -> a -> Vec n a -> Vec n a
+ Termonad.Config.Vec: singletonVec :: a -> Vec N1 a
+ Termonad.Config.Vec: subtractPeano :: Peano -> Peano -> Peano
+ Termonad.Config.Vec: takeVec :: IFin n m -> Vec n a -> Vec m a
+ Termonad.Config.Vec: toFinIFin :: IFin n m -> Fin n
+ Termonad.Config.Vec: toIntFin :: Fin n -> Int
+ Termonad.Config.Vec: toIntIFin :: IFin n m -> Int
+ Termonad.Config.Vec: toListMatrix :: forall (peanos :: [Peano]) (a :: Type). Sing peanos -> Matrix peanos a -> [a]
+ Termonad.Config.Vec: type Abs_6989586621679401487Sym1 (t_a1DTH :: Peano) = Abs_6989586621679401487 t_a1DTH
+ Termonad.Config.Vec: type AddPeanoSym2 (t_a1Dsk :: Peano) (t_a1Dsl :: Peano) = AddPeano t_a1Dsk t_a1Dsl
+ Termonad.Config.Vec: type Compare_6989586621679400935Sym2 (t_a1DKN :: Peano) (t_a1DKO :: Peano) = Compare_6989586621679400935 t_a1DKN t_a1DKO
+ Termonad.Config.Vec: type FromInteger_6989586621679401522Sym1 (t_a1DUg :: Nat) = FromInteger_6989586621679401522 t_a1DUg
+ Termonad.Config.Vec: type Let6989586621679401507Scrutinee_6989586621679389242Sym1 t_a1DU0 = Let6989586621679401507Scrutinee_6989586621679389242 t_a1DU0
+ Termonad.Config.Vec: type Let6989586621679401513Scrutinee_6989586621679389244Sym1 t_a1DU6 = Let6989586621679401513Scrutinee_6989586621679389244 t_a1DU6
+ Termonad.Config.Vec: type MatrixTFSym2 (ns :: [Peano]) (t :: Type) = (MatrixTF ns t :: Type)
+ Termonad.Config.Vec: type MultPeanoSym2 (t_a1Dsw :: Peano) (t_a1Dsx :: Peano) = MultPeano t_a1Dsw t_a1Dsx
+ Termonad.Config.Vec: type N0Sym0 = N0
+ Termonad.Config.Vec: type N10Sym0 = N10
+ Termonad.Config.Vec: type N1Sym0 = N1
+ Termonad.Config.Vec: type N24Sym0 = N24
+ Termonad.Config.Vec: type N2Sym0 = N2
+ Termonad.Config.Vec: type N3Sym0 = N3
+ Termonad.Config.Vec: type N4Sym0 = N4
+ Termonad.Config.Vec: type N5Sym0 = N5
+ Termonad.Config.Vec: type N6Sym0 = N6
+ Termonad.Config.Vec: type N7Sym0 = N7
+ Termonad.Config.Vec: type N8Sym0 = N8
+ Termonad.Config.Vec: type N9Sym0 = N9
+ Termonad.Config.Vec: type SPeano = (Sing :: Peano -> Type)
+ Termonad.Config.Vec: type SSym1 (t_a1Ds5 :: Peano) = S t_a1Ds5
+ Termonad.Config.Vec: type ShowsPrec_6989586621679401357Sym3 (t_a1DRB :: Nat) (t_a1DRC :: Peano) (t_a1DRD :: Symbol) = ShowsPrec_6989586621679401357 t_a1DRB t_a1DRC t_a1DRD
+ Termonad.Config.Vec: type Signum_6989586621679401497Sym1 (t_a1DTR :: Peano) = Signum_6989586621679401497 t_a1DTR
+ Termonad.Config.Vec: type SubtractPeanoSym2 (t_a1Ds8 :: Peano) (t_a1Ds9 :: Peano) = SubtractPeano t_a1Ds8 t_a1Ds9
+ Termonad.Config.Vec: type TFHelper_6989586621679401418Sym2 (t_a1DSA :: Peano) (t_a1DSB :: Peano) = TFHelper_6989586621679401418 t_a1DSA t_a1DSB
+ Termonad.Config.Vec: type TFHelper_6989586621679401444Sym2 (t_a1DT0 :: Peano) (t_a1DT1 :: Peano) = TFHelper_6989586621679401444 t_a1DT0 t_a1DT1
+ Termonad.Config.Vec: type TFHelper_6989586621679401470Sym2 (t_a1DTq :: Peano) (t_a1DTr :: Peano) = TFHelper_6989586621679401470 t_a1DTq t_a1DTr
+ Termonad.Config.Vec: type ZSym0 = Z
+ Termonad.Config.Vec: updateAtMatrix :: HList Fin ns -> (a -> a) -> Matrix ns a -> Matrix ns a
+ Termonad.Config.Vec: updateAtVec :: Fin n -> (a -> a) -> Vec n a -> Vec n a
+ Termonad.Gtk: widgetEq :: (MonadIO m, IsWidget a, IsWidget b) => a -> b -> m Bool
+ Termonad.Lenses: _FontSizePoints :: Prism' FontSize Int
+ Termonad.Lenses: _FontSizeUnits :: Prism' FontSize Double
+ Termonad.Lenses: lensConfirmExit :: Lens' ConfigOptions Bool
+ Termonad.Lenses: lensCreateTermHook :: Iso' ConfigHooks (TMState -> Terminal -> IO ())
+ Termonad.Lenses: lensCursorBlinkMode :: Lens' ConfigOptions CursorBlinkMode
+ Termonad.Lenses: lensFontConfig :: Lens' ConfigOptions FontConfig
+ Termonad.Lenses: lensFontFamily :: Lens' FontConfig Text
+ Termonad.Lenses: lensFontSize :: Lens' FontConfig FontSize
+ Termonad.Lenses: lensHooks :: Lens' TMConfig ConfigHooks
+ Termonad.Lenses: lensOptions :: Lens' TMConfig ConfigOptions
+ Termonad.Lenses: lensPid :: Lens' TMTerm Int
+ Termonad.Lenses: lensScrollbackLen :: Lens' ConfigOptions Integer
+ Termonad.Lenses: lensShowMenu :: Lens' ConfigOptions Bool
+ Termonad.Lenses: lensShowScrollbar :: Lens' ConfigOptions ShowScrollbar
+ Termonad.Lenses: lensShowTabBar :: Lens' ConfigOptions ShowTabBar
+ Termonad.Lenses: lensTMNotebook :: Lens' TMNotebook Notebook
+ Termonad.Lenses: lensTMNotebookTabLabel :: Lens' TMNotebookTab Label
+ Termonad.Lenses: lensTMNotebookTabTerm :: Lens' TMNotebookTab TMTerm
+ Termonad.Lenses: lensTMNotebookTabTermContainer :: Lens' TMNotebookTab ScrolledWindow
+ Termonad.Lenses: lensTMNotebookTabs :: Lens' TMNotebook (FocusList TMNotebookTab)
+ Termonad.Lenses: lensTMStateApp :: Lens' TMState' Application
+ Termonad.Lenses: lensTMStateAppWin :: Lens' TMState' ApplicationWindow
+ Termonad.Lenses: lensTMStateConfig :: Lens' TMState' TMConfig
+ Termonad.Lenses: lensTMStateFontDesc :: Lens' TMState' FontDescription
+ Termonad.Lenses: lensTMStateNotebook :: Lens' TMState' TMNotebook
+ Termonad.Lenses: lensTerm :: Lens' TMTerm Terminal
+ Termonad.Lenses: lensUnique :: Lens' TMTerm Unique
+ Termonad.Lenses: lensWordCharExceptions :: Lens' ConfigOptions Text
+ Termonad.Prelude: ($!!) :: NFData a => a -> b -> a -> b
+ Termonad.Prelude: ($!) :: () => a -> b -> a -> b
+ Termonad.Prelude: ($) :: () => a -> b -> a -> b
+ Termonad.Prelude: ($>) :: Functor f => f a -> b -> f b
+ Termonad.Prelude: (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
+ Termonad.Prelude: (&&) :: Bool -> Bool -> Bool
+ Termonad.Prelude: (&) :: () => a -> a -> b -> b
+ Termonad.Prelude: (*) :: Num a => a -> a -> a
+ Termonad.Prelude: (**) :: Floating a => a -> a -> a
+ Termonad.Prelude: (***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c')
+ Termonad.Prelude: (*>) :: Applicative f => f a -> f b -> f b
+ Termonad.Prelude: (+) :: Num a => a -> a -> a
+ Termonad.Prelude: (++) :: Monoid m => m -> m -> m
+ Termonad.Prelude: (-) :: Num a => a -> a -> a
+ Termonad.Prelude: (.) :: Category cat => cat b c -> cat a b -> cat a c
+ Termonad.Prelude: (/) :: Fractional a => a -> a -> a
+ Termonad.Prelude: (/=) :: Eq a => a -> a -> Bool
+ Termonad.Prelude: (<$) :: Functor f => a -> f b -> f a
+ Termonad.Prelude: (<$>) :: Functor f => a -> b -> f a -> f b
+ Termonad.Prelude: (<&&>) :: Applicative a => a Bool -> a Bool -> a Bool
+ Termonad.Prelude: (<&>) :: Functor f => f a -> a -> b -> f b
+ Termonad.Prelude: (<) :: Ord a => a -> a -> Bool
+ Termonad.Prelude: (<*) :: Applicative f => f a -> f b -> f a
+ Termonad.Prelude: (<**>) :: Applicative f => f a -> f a -> b -> f b
+ Termonad.Prelude: (<*>) :: Applicative f => f a -> b -> f a -> f b
+ Termonad.Prelude: (<.>) :: FilePath -> String -> FilePath
+ Termonad.Prelude: (</>) :: FilePath -> FilePath -> FilePath
+ Termonad.Prelude: (<=) :: Ord a => a -> a -> Bool
+ Termonad.Prelude: (<=<) :: Monad m => b -> m c -> a -> m b -> a -> m c
+ Termonad.Prelude: (<>) :: Semigroup a => a -> a -> a
+ Termonad.Prelude: (<|) :: SemiSequence seq => Element seq -> NonNull seq -> NonNull seq
+ Termonad.Prelude: (<|>) :: Alternative f => f a -> f a -> f a
+ Termonad.Prelude: (<||>) :: Applicative a => a Bool -> a Bool -> a Bool
+ Termonad.Prelude: (=<<) :: Monad m => a -> m b -> m a -> m b
+ Termonad.Prelude: (==) :: Eq a => a -> a -> Bool
+ Termonad.Prelude: (>) :: Ord a => a -> a -> Bool
+ Termonad.Prelude: (>=) :: Ord a => a -> a -> Bool
+ Termonad.Prelude: (>=>) :: Monad m => a -> m b -> b -> m c -> a -> m c
+ Termonad.Prelude: (>>) :: Monad m => m a -> m b -> m b
+ Termonad.Prelude: (>>=) :: Monad m => m a -> a -> m b -> m b
+ Termonad.Prelude: (\\) :: SetContainer a => a -> a -> a
+ Termonad.Prelude: (^) :: (Num a, Integral b) => a -> b -> a
+ Termonad.Prelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
+ Termonad.Prelude: (||) :: Bool -> Bool -> Bool
+ Termonad.Prelude: -> * -> *) key :: Constraint;
+ Termonad.Prelude: AppendMode :: IOMode
+ Termonad.Prelude: BlockBuffering :: Maybe Int -> BufferMode
+ Termonad.Prelude: Concurrently :: m a -> Concurrently a
+ Termonad.Prelude: Down :: a -> Down a
+ Termonad.Prelude: EQ :: Ordering
+ Termonad.Prelude: False :: Bool
+ Termonad.Prelude: GT :: Ordering
+ Termonad.Prelude: Identity :: a -> Identity a
+ Termonad.Prelude: Just :: a -> Maybe a
+ Termonad.Prelude: KProxy :: KProxy t
+ Termonad.Prelude: LT :: Ordering
+ Termonad.Prelude: Left :: a -> Either a b
+ Termonad.Prelude: LineBuffering :: BufferMode
+ Termonad.Prelude: ModifiedJulianDay :: Integer -> Day
+ Termonad.Prelude: MutVar :: MutVar# s a -> MutVar s a
+ Termonad.Prelude: NoBuffering :: BufferMode
+ Termonad.Prelude: Nothing :: Maybe a
+ Termonad.Prelude: Proxy :: Proxy
+ Termonad.Prelude: ReadMode :: IOMode
+ Termonad.Prelude: ReadWriteMode :: IOMode
+ Termonad.Prelude: ReaderT :: r -> m a -> ReaderT r
+ Termonad.Prelude: Right :: b -> Either a b
+ Termonad.Prelude: StringException :: String -> CallStack -> StringException
+ Termonad.Prelude: True :: Bool
+ Termonad.Prelude: UTCTime :: Day -> DiffTime -> UTCTime
+ Termonad.Prelude: UnliftIO :: forall a. () => m a -> IO a -> UnliftIO
+ Termonad.Prelude: WriteMode :: IOMode
+ Termonad.Prelude: [AsyncExceptionWrapper] :: AsyncExceptionWrapper
+ Termonad.Prelude: [Handler] :: Handler m a
+ Termonad.Prelude: [SomeAsyncException] :: SomeAsyncException
+ Termonad.Prelude: [SomeException] :: SomeException
+ Termonad.Prelude: [SyncExceptionWrapper] :: SyncExceptionWrapper
+ Termonad.Prelude: [runConcurrently] :: Concurrently a -> m a
+ Termonad.Prelude: [runIdentity] :: Identity a -> a
+ Termonad.Prelude: [runReaderT] :: ReaderT r -> r -> m a
+ Termonad.Prelude: [toModifiedJulianDay] :: Day -> Integer
+ Termonad.Prelude: [unliftIO] :: UnliftIO -> forall a. () => m a -> IO a
+ Termonad.Prelude: [utctDayTime] :: UTCTime -> DiffTime
+ Termonad.Prelude: [utctDay] :: UTCTime -> Day
+ Termonad.Prelude: abs :: Num a => a -> a
+ Termonad.Prelude: acos :: Floating a => a -> a
+ Termonad.Prelude: acosh :: Floating a => a -> a
+ Termonad.Prelude: adjustMap :: IsMap map => MapValue map -> MapValue map -> ContainerKey map -> map -> map
+ Termonad.Prelude: adjustWithKey :: IsMap map => ContainerKey map -> MapValue map -> MapValue map -> ContainerKey map -> map -> map
+ Termonad.Prelude: all :: MonoFoldable mono => Element mono -> Bool -> mono -> Bool
+ Termonad.Prelude: alreadyExistsErrorType :: IOErrorType
+ Termonad.Prelude: alreadyInUseErrorType :: IOErrorType
+ Termonad.Prelude: alterMap :: IsMap map => Maybe MapValue map -> Maybe MapValue map -> ContainerKey map -> map -> map
+ Termonad.Prelude: alwaysSTM :: STM Bool -> STM ()
+ Termonad.Prelude: alwaysSucceedsSTM :: () => STM a -> STM ()
+ Termonad.Prelude: and :: (MonoFoldable mono, Element mono ~ Bool) => mono -> Bool
+ Termonad.Prelude: annotateIOError :: IOError -> String -> Maybe Handle -> Maybe FilePath -> IOError
+ Termonad.Prelude: any :: MonoFoldable mono => Element mono -> Bool -> mono -> Bool
+ Termonad.Prelude: ap :: Monad m => m a -> b -> m a -> m b
+ Termonad.Prelude: applyDList :: () => DList a -> [a] -> [a]
+ Termonad.Prelude: asBDeque :: () => BDeque s a -> BDeque s a
+ Termonad.Prelude: asBRef :: () => BRef s a -> BRef s a
+ Termonad.Prelude: asByteString :: ByteString -> ByteString
+ Termonad.Prelude: asDLList :: () => DLList s a -> DLList s a
+ Termonad.Prelude: asDList :: () => DList a -> DList a
+ Termonad.Prelude: asHashMap :: () => HashMap k v -> HashMap k v
+ Termonad.Prelude: asHashSet :: () => HashSet a -> HashSet a
+ Termonad.Prelude: asIORef :: () => IORef a -> IORef a
+ Termonad.Prelude: asIntMap :: () => IntMap v -> IntMap v
+ Termonad.Prelude: asIntSet :: IntSet -> IntSet
+ Termonad.Prelude: asLByteString :: LByteString -> LByteString
+ Termonad.Prelude: asLText :: LText -> LText
+ Termonad.Prelude: asList :: () => [a] -> [a]
+ Termonad.Prelude: asMap :: () => Map k v -> Map k v
+ Termonad.Prelude: asMaybe :: () => Maybe a -> Maybe a
+ Termonad.Prelude: asMutVar :: () => MutVar s a -> MutVar s a
+ Termonad.Prelude: asPRef :: () => PRef s a -> PRef s a
+ Termonad.Prelude: asProxyTypeOf :: () => a -> proxy a -> a
+ Termonad.Prelude: asSDeque :: () => SDeque s a -> SDeque s a
+ Termonad.Prelude: asSRef :: () => SRef s a -> SRef s a
+ Termonad.Prelude: asSTRef :: () => STRef s a -> STRef s a
+ Termonad.Prelude: asSVector :: () => SVector a -> SVector a
+ Termonad.Prelude: asSet :: () => Set a -> Set a
+ Termonad.Prelude: asString :: [Char] -> [Char]
+ Termonad.Prelude: asText :: Text -> Text
+ Termonad.Prelude: asTypeOf :: () => a -> a -> a
+ Termonad.Prelude: asUDeque :: () => UDeque s a -> UDeque s a
+ Termonad.Prelude: asURef :: () => URef s a -> URef s a
+ Termonad.Prelude: asUVector :: () => UVector a -> UVector a
+ Termonad.Prelude: asVector :: () => Vector a -> Vector a
+ Termonad.Prelude: asin :: Floating a => a -> a
+ Termonad.Prelude: asinh :: Floating a => a -> a
+ Termonad.Prelude: ask :: MonadReader r m => m r
+ Termonad.Prelude: askRunInIO :: MonadUnliftIO m => m m a -> IO a
+ Termonad.Prelude: askUnliftIO :: MonadUnliftIO m => m UnliftIO m
+ Termonad.Prelude: asks :: MonadReader r m => r -> a -> m a
+ Termonad.Prelude: assert :: () => Bool -> a -> a
+ Termonad.Prelude: asum :: (Foldable t, Alternative f) => t f a -> f a
+ Termonad.Prelude: async :: MonadUnliftIO m => m a -> m Async a
+ Termonad.Prelude: asyncBound :: MonadUnliftIO m => m a -> m Async a
+ Termonad.Prelude: asyncOn :: MonadUnliftIO m => Int -> m a -> m Async a
+ Termonad.Prelude: asyncOnWithUnmask :: MonadUnliftIO m => Int -> forall b. () => m b -> m b -> m a -> m Async a
+ Termonad.Prelude: asyncWithUnmask :: MonadUnliftIO m => forall b. () => m b -> m b -> m a -> m Async a
+ Termonad.Prelude: atan :: Floating a => a -> a
+ Termonad.Prelude: atan2 :: RealFloat a => a -> a -> a
+ Termonad.Prelude: atanh :: Floating a => a -> a
+ Termonad.Prelude: atomicModifyIORef :: MonadIO m => IORef a -> a -> (a, b) -> m b
+ Termonad.Prelude: atomicModifyIORef' :: MonadIO m => IORef a -> a -> (a, b) -> m b
+ Termonad.Prelude: atomicModifyMutVar :: PrimMonad m => MutVar PrimState m a -> a -> (a, b) -> m b
+ Termonad.Prelude: atomicModifyMutVar' :: PrimMonad m => MutVar PrimState m a -> a -> (a, b) -> m b
+ Termonad.Prelude: atomicModifyRef :: (MutableAtomicRef c, PrimMonad m, PrimState m ~ MCState c) => c -> RefElement c -> (RefElement c, a) -> m a
+ Termonad.Prelude: atomicModifyRef' :: (MutableAtomicRef c, PrimMonad m, PrimState m ~ MCState c) => c -> RefElement c -> (RefElement c, a) -> m a
+ Termonad.Prelude: atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()
+ Termonad.Prelude: atomically :: MonadIO m => STM a -> m a
+ Termonad.Prelude: bimap :: Bifunctor p => a -> b -> c -> d -> p a c -> p b d
+ Termonad.Prelude: bool :: () => a -> a -> Bool -> a
+ Termonad.Prelude: bracket :: MonadUnliftIO m => m a -> a -> m b -> a -> m c -> m c
+ Termonad.Prelude: bracketOnError :: MonadUnliftIO m => m a -> a -> m b -> a -> m c -> m c
+ Termonad.Prelude: bracketOnError_ :: MonadUnliftIO m => m a -> m b -> m c -> m c
+ Termonad.Prelude: bracket_ :: MonadUnliftIO m => m a -> m b -> m c -> m c
+ Termonad.Prelude: break :: IsSequence seq => Element seq -> Bool -> seq -> (seq, seq)
+ Termonad.Prelude: breakLine :: Textual t => t -> (t, t)
+ Termonad.Prelude: breakWord :: Textual t => t -> (t, t)
+ Termonad.Prelude: builderToLazy :: Builder builder lazy => builder -> lazy
+ Termonad.Prelude: cancel :: MonadIO m => Async a -> m ()
+ Termonad.Prelude: cancelWith :: (Exception e, MonadIO m) => Async a -> e -> m ()
+ Termonad.Prelude: catMaybes :: (IsSequence f Maybe t, Functor f, Element f Maybe t ~ Maybe t) => f Maybe t -> f t
+ Termonad.Prelude: catch :: (MonadUnliftIO m, Exception e) => m a -> e -> m a -> m a
+ Termonad.Prelude: catchAny :: MonadUnliftIO m => m a -> SomeException -> m a -> m a
+ Termonad.Prelude: catchAnyDeep :: (NFData a, MonadUnliftIO m) => m a -> SomeException -> m a -> m a
+ Termonad.Prelude: catchDeep :: (MonadUnliftIO m, Exception e, NFData a) => m a -> e -> m a -> m a
+ Termonad.Prelude: catchIO :: MonadUnliftIO m => m a -> IOException -> m a -> m a
+ Termonad.Prelude: catchJust :: (MonadUnliftIO m, Exception e) => e -> Maybe b -> m a -> b -> m a -> m a
+ Termonad.Prelude: catches :: MonadUnliftIO m => m a -> [Handler m a] -> m a
+ Termonad.Prelude: catchesDeep :: (MonadUnliftIO m, NFData a) => m a -> [Handler m a] -> m a
+ Termonad.Prelude: ceiling :: (RealFrac a, Integral b) => a -> b
+ Termonad.Prelude: charToLower :: Char -> Char
+ Termonad.Prelude: charToUpper :: Char -> Char
+ Termonad.Prelude: checkSTM :: Bool -> STM ()
+ Termonad.Prelude: class Applicative f => Alternative (f :: * -> *)
+ Termonad.Prelude: class Functor f => Applicative (f :: * -> *)
+ Termonad.Prelude: class BiPolyMap (map :: * -> * -> *) where {
+ Termonad.Prelude: class Bifunctor (p :: * -> * -> *)
+ Termonad.Prelude: class Bounded a
+ Termonad.Prelude: class Monoid builder => Builder builder lazy | builder -> lazy, lazy -> builder
+ Termonad.Prelude: class Enum a
+ Termonad.Prelude: class Eq a
+ Termonad.Prelude: class (Typeable e, Show e) => Exception e
+ Termonad.Prelude: class Fractional a => Floating a
+ Termonad.Prelude: class Foldable (t :: * -> *)
+ Termonad.Prelude: class Num a => Fractional a
+ Termonad.Prelude: class Functor (f :: * -> *)
+ Termonad.Prelude: class Generic a
+ Termonad.Prelude: class MonoFoldable mono => GrowingAppend mono
+ Termonad.Prelude: class SetContainer set => HasKeysSet set where {
+ Termonad.Prelude: class Hashable a
+ Termonad.Prelude: class (Real a, Enum a) => Integral a
+ Termonad.Prelude: class (MonoTraversable map, SetContainer map) => IsMap map where {
+ Termonad.Prelude: class (Monoid seq, MonoTraversable seq, SemiSequence seq, MonoPointed seq) => IsSequence seq
+ Termonad.Prelude: class (SetContainer set, Element set ~ ContainerKey set) => IsSet set
+ Termonad.Prelude: class IsString a
+ Termonad.Prelude: class (IsSequence lazy, IsSequence strict) => LazySequence lazy strict | lazy -> strict, strict -> lazy
+ Termonad.Prelude: class Applicative m => Monad (m :: * -> *)
+ Termonad.Prelude: class Monad m => MonadIO (m :: * -> *)
+ Termonad.Prelude: class (Alternative m, Monad m) => MonadPlus (m :: * -> *)
+ Termonad.Prelude: class Monad m => MonadReader r (m :: * -> *) | m -> r
+ Termonad.Prelude: class MonadIO m => MonadUnliftIO (m :: * -> *)
+ Termonad.Prelude: class MonoFunctor mono => MonoComonad mono
+ Termonad.Prelude: class MonoFoldable mono
+ Termonad.Prelude: class MonoFunctor mono
+ Termonad.Prelude: class MonoPointed mono
+ Termonad.Prelude: class (MonoFunctor mono, MonoFoldable mono) => MonoTraversable mono
+ Termonad.Prelude: class MonoFunctor mono => MonoZip mono
+ Termonad.Prelude: class Semigroup a => Monoid a
+ Termonad.Prelude: class MutableRef c => MutableAtomicRef c
+ Termonad.Prelude: class MutableContainer c => MutableCollection c where {
+ Termonad.Prelude: class MutableContainer c where {
+ Termonad.Prelude: class MutableCollection c => MutablePopBack c
+ Termonad.Prelude: class MutableCollection c => MutablePopFront c
+ Termonad.Prelude: class MutableCollection c => MutablePushBack c
+ Termonad.Prelude: class MutableCollection c => MutablePushFront c
+ Termonad.Prelude: class MutableContainer c => MutableRef c where {
+ Termonad.Prelude: class NFData a
+ Termonad.Prelude: class Num a
+ Termonad.Prelude: class Eq a => Ord a
+ Termonad.Prelude: class PolyMap (map :: * -> *)
+ Termonad.Prelude: class Prim a
+ Termonad.Prelude: class Monad m => PrimMonad (m :: * -> *) where {
+ Termonad.Prelude: class Read a
+ Termonad.Prelude: class (Num a, Ord a) => Real a
+ Termonad.Prelude: class (RealFrac a, Floating a) => RealFloat a
+ Termonad.Prelude: class (Real a, Fractional a) => RealFrac a
+ Termonad.Prelude: class (Integral Index seq, GrowingAppend seq) => SemiSequence seq where {
+ Termonad.Prelude: class Semigroup a
+ Termonad.Prelude: class (Monoid set, Semigroup set, MonoFoldable set, Eq ContainerKey set, GrowingAppend set) => SetContainer set where {
+ Termonad.Prelude: class Show a
+ Termonad.Prelude: class Storable a
+ Termonad.Prelude: class (IsSequence t, IsString t, Element t ~ Char) => Textual t
+ Termonad.Prelude: class ToBuilder value builder
+ Termonad.Prelude: class (Functor t, Foldable t) => Traversable (t :: * -> *)
+ Termonad.Prelude: class Typeable (a :: k)
+ Termonad.Prelude: class (Vector Vector a, MVector MVector a) => Unbox a
+ Termonad.Prelude: class (Textual textual, IsSequence binary) => Utf8 textual binary | textual -> binary, binary -> textual
+ Termonad.Prelude: cloneTChan :: () => TChan a -> STM TChan a
+ Termonad.Prelude: closeTBMChan :: () => TBMChan a -> STM ()
+ Termonad.Prelude: closeTBMQueue :: () => TBMQueue a -> STM ()
+ Termonad.Prelude: closeTMChan :: () => TMChan a -> STM ()
+ Termonad.Prelude: closeTMQueue :: () => TMQueue a -> STM ()
+ Termonad.Prelude: compare :: Ord a => a -> a -> Ordering
+ Termonad.Prelude: compareLength :: (MonoFoldable mono, Integral i) => mono -> i -> Ordering
+ Termonad.Prelude: comparing :: Ord a => b -> a -> b -> b -> Ordering
+ Termonad.Prelude: concat :: (MonoFoldable mono, Monoid Element mono) => mono -> Element mono
+ Termonad.Prelude: concatMap :: (MonoFoldable mono, Monoid m) => Element mono -> m -> mono -> m
+ Termonad.Prelude: concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)
+ Termonad.Prelude: concurrently_ :: MonadUnliftIO m => m a -> m b -> m ()
+ Termonad.Prelude: cons :: SemiSequence seq => Element seq -> seq -> seq
+ Termonad.Prelude: const :: () => a -> b -> a
+ Termonad.Prelude: cos :: Floating a => a -> a
+ Termonad.Prelude: cosh :: Floating a => a -> a
+ Termonad.Prelude: curry :: () => (a, b) -> c -> a -> b -> c
+ Termonad.Prelude: data Async a
+ Termonad.Prelude: data AsyncExceptionWrapper
+ Termonad.Prelude: data BRef s a
+ Termonad.Prelude: data Bool
+ Termonad.Prelude: data BufferMode
+ Termonad.Prelude: data ByteString
+ Termonad.Prelude: data Chan a
+ Termonad.Prelude: data Char
+ Termonad.Prelude: data DLList s a
+ Termonad.Prelude: data DList a
+ Termonad.Prelude: data Deque (v :: * -> * -> *) s a
+ Termonad.Prelude: data Double
+ Termonad.Prelude: data Either a b
+ Termonad.Prelude: data Float
+ Termonad.Prelude: data Handle
+ Termonad.Prelude: data Handler (m :: * -> *) a
+ Termonad.Prelude: data HashMap k v
+ Termonad.Prelude: data HashSet a
+ Termonad.Prelude: data IO a
+ Termonad.Prelude: data IOErrorType
+ Termonad.Prelude: data IOException
+ Termonad.Prelude: data IOMode
+ Termonad.Prelude: data IORef a
+ Termonad.Prelude: data Int
+ Termonad.Prelude: data Int32
+ Termonad.Prelude: data Int64
+ Termonad.Prelude: data IntMap a
+ Termonad.Prelude: data IntSet
+ Termonad.Prelude: data Integer
+ Termonad.Prelude: data KProxy t
+ Termonad.Prelude: data MVar a
+ Termonad.Prelude: data Map k a
+ Termonad.Prelude: data Maybe a
+ Termonad.Prelude: data Memoized a
+ Termonad.Prelude: data MutVar s a
+ Termonad.Prelude: data NonNull mono
+ Termonad.Prelude: data Ordering
+ Termonad.Prelude: data PRef s a
+ Termonad.Prelude: data RealWorld
+ Termonad.Prelude: data SRef s a
+ Termonad.Prelude: data STM a
+ Termonad.Prelude: data STRef s a
+ Termonad.Prelude: data SeekMode
+ Termonad.Prelude: data Seq a
+ Termonad.Prelude: data Set a
+ Termonad.Prelude: data SomeAsyncException
+ Termonad.Prelude: data SomeException
+ Termonad.Prelude: data StringException
+ Termonad.Prelude: data SyncExceptionWrapper
+ Termonad.Prelude: data TBChan a
+ Termonad.Prelude: data TBMChan a
+ Termonad.Prelude: data TBMQueue a
+ Termonad.Prelude: data TBQueue a
+ Termonad.Prelude: data TChan a
+ Termonad.Prelude: data TMChan a
+ Termonad.Prelude: data TMQueue a
+ Termonad.Prelude: data TMVar a
+ Termonad.Prelude: data TQueue a
+ Termonad.Prelude: data TVar a
+ Termonad.Prelude: data Text
+ Termonad.Prelude: data URef s a
+ Termonad.Prelude: data UTCTime
+ Termonad.Prelude: data Vector a
+ Termonad.Prelude: data Word
+ Termonad.Prelude: data Word32
+ Termonad.Prelude: data Word64
+ Termonad.Prelude: data Word8
+ Termonad.Prelude: data WrappedMonoid m
+ Termonad.Prelude: data Proxy (t :: k) :: forall k. () => k -> *
+ Termonad.Prelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
+ Termonad.Prelude: decodeUtf8 :: Utf8 textual binary => binary -> textual
+ Termonad.Prelude: deepseq :: NFData a => a -> b -> b
+ Termonad.Prelude: defaultCons :: IsSequence seq => Element seq -> seq -> seq
+ Termonad.Prelude: defaultFind :: MonoFoldable seq => Element seq -> Bool -> seq -> Maybe Element seq
+ Termonad.Prelude: defaultIntersperse :: IsSequence seq => Element seq -> seq -> seq
+ Termonad.Prelude: defaultReverse :: IsSequence seq => seq -> seq
+ Termonad.Prelude: defaultSnoc :: IsSequence seq => seq -> Element seq -> seq
+ Termonad.Prelude: defaultSortBy :: IsSequence seq => Element seq -> Element seq -> Ordering -> seq -> seq
+ Termonad.Prelude: defaultSplitWhen :: IsSequence seq => Element seq -> Bool -> seq -> [seq]
+ Termonad.Prelude: defaultTimeLocale :: TimeLocale
+ Termonad.Prelude: delete :: (IsSequence seq, Eq Element seq) => Element seq -> seq -> seq
+ Termonad.Prelude: deleteBy :: (IsSequence seq, Eq Element seq) => Element seq -> Element seq -> Bool -> Element seq -> seq -> seq
+ Termonad.Prelude: deleteMap :: IsMap map => ContainerKey map -> map -> map
+ Termonad.Prelude: deleteSet :: IsSet set => Element set -> set -> set
+ Termonad.Prelude: difference :: SetContainer set => set -> set -> set
+ Termonad.Prelude: differenceMap :: PolyMap map => map value1 -> map value2 -> map value1
+ Termonad.Prelude: displayException :: Exception e => e -> String
+ Termonad.Prelude: div :: Integral a => a -> a -> a
+ Termonad.Prelude: divMod :: Integral a => a -> a -> (a, a)
+ Termonad.Prelude: doesNotExistErrorType :: IOErrorType
+ Termonad.Prelude: drop :: IsSequence seq => Index seq -> seq -> seq
+ Termonad.Prelude: dropEnd :: IsSequence seq => Index seq -> seq -> seq
+ Termonad.Prelude: dropPrefix :: (IsSequence seq, Eq Element seq) => seq -> seq -> seq
+ Termonad.Prelude: dropSuffix :: (IsSequence seq, Eq Element seq) => seq -> seq -> seq
+ Termonad.Prelude: dropWhile :: IsSequence seq => Element seq -> Bool -> seq -> seq
+ Termonad.Prelude: dupChan :: MonadIO m => Chan a -> m Chan a
+ Termonad.Prelude: dupTChan :: () => TChan a -> STM TChan a
+ Termonad.Prelude: dupTMChan :: () => TMChan a -> STM TMChan a
+ Termonad.Prelude: either :: () => a -> c -> b -> c -> Either a b -> c
+ Termonad.Prelude: elem :: (MonoFoldable mono, Eq Element mono) => Element mono -> mono -> Bool
+ Termonad.Prelude: empty :: Alternative f => f a
+ Termonad.Prelude: encodeFloat :: RealFloat a => Integer -> Int -> a
+ Termonad.Prelude: encodeUtf8 :: Utf8 textual binary => textual -> binary
+ Termonad.Prelude: ensurePrefix :: (Eq Element seq, IsSequence seq) => seq -> seq -> seq
+ Termonad.Prelude: ensureSuffix :: (Eq Element seq, IsSequence seq) => seq -> seq -> seq
+ Termonad.Prelude: enumFrom :: Enum a => a -> [a]
+ Termonad.Prelude: enumFromThen :: Enum a => a -> a -> [a]
+ Termonad.Prelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
+ Termonad.Prelude: enumFromTo :: Enum a => a -> a -> [a]
+ Termonad.Prelude: eofErrorType :: IOErrorType
+ Termonad.Prelude: equating :: Eq a => b -> a -> b -> b -> Bool
+ Termonad.Prelude: error :: HasCallStack => [Char] -> a
+ Termonad.Prelude: estimateFreeSlotsTBChan :: () => TBChan a -> STM Int
+ Termonad.Prelude: estimateFreeSlotsTBMChan :: () => TBMChan a -> STM Int
+ Termonad.Prelude: estimateFreeSlotsTBMQueue :: () => TBMQueue a -> STM Int
+ Termonad.Prelude: evaluate :: MonadIO m => a -> m a
+ Termonad.Prelude: evaluateDeep :: (MonadIO m, NFData a) => a -> m a
+ Termonad.Prelude: even :: Integral a => a -> Bool
+ Termonad.Prelude: exp :: Floating a => a -> a
+ Termonad.Prelude: exponent :: RealFloat a => a -> Int
+ Termonad.Prelude: fail :: Monad m => String -> m a
+ Termonad.Prelude: filter :: IsSequence seq => Element seq -> Bool -> seq -> seq
+ Termonad.Prelude: filterM :: (IsSequence seq, Monad m) => Element seq -> m Bool -> seq -> m seq
+ Termonad.Prelude: filterMap :: IsMap map => MapValue map -> Bool -> map -> map
+ Termonad.Prelude: finally :: MonadUnliftIO m => m a -> m b -> m a
+ Termonad.Prelude: find :: SemiSequence seq => Element seq -> Bool -> seq -> Maybe Element seq
+ Termonad.Prelude: findWithDefault :: IsMap map => MapValue map -> ContainerKey map -> map -> MapValue map
+ Termonad.Prelude: first :: Bifunctor p => a -> b -> p a c -> p b c
+ Termonad.Prelude: flip :: () => a -> b -> c -> b -> a -> c
+ Termonad.Prelude: floatDigits :: RealFloat a => a -> Int
+ Termonad.Prelude: floatRadix :: RealFloat a => a -> Integer
+ Termonad.Prelude: floatRange :: RealFloat a => a -> (Int, Int)
+ Termonad.Prelude: floor :: (RealFrac a, Integral b) => a -> b
+ Termonad.Prelude: flushBuilder :: Builder builder lazy => builder
+ Termonad.Prelude: fmap :: Functor f => a -> b -> f a -> f b
+ Termonad.Prelude: fold :: (MonoFoldable mono, Monoid Element mono) => mono -> Element mono
+ Termonad.Prelude: foldM :: (MonoFoldable mono, Monad m) => a -> Element mono -> m a -> a -> mono -> m a
+ Termonad.Prelude: foldMap :: (MonoFoldable mono, Monoid m) => Element mono -> m -> mono -> m
+ Termonad.Prelude: foldMap1Ex :: (MonoFoldable mono, Semigroup m) => Element mono -> m -> mono -> m
+ Termonad.Prelude: foldl' :: MonoFoldable mono => a -> Element mono -> a -> a -> mono -> a
+ Termonad.Prelude: foldl1Ex' :: MonoFoldable mono => Element mono -> Element mono -> Element mono -> mono -> Element mono
+ Termonad.Prelude: foldlM :: (MonoFoldable mono, Monad m) => a -> Element mono -> m a -> a -> mono -> m a
+ Termonad.Prelude: foldr :: MonoFoldable mono => Element mono -> b -> b -> b -> mono -> b
+ Termonad.Prelude: foldr1Ex :: MonoFoldable mono => Element mono -> Element mono -> Element mono -> mono -> Element mono
+ Termonad.Prelude: for :: (Traversable t, Applicative f) => t a -> a -> f b -> f t b
+ Termonad.Prelude: forConcurrently :: (MonadUnliftIO m, Traversable t) => t a -> a -> m b -> m t b
+ Termonad.Prelude: forConcurrently_ :: (MonadUnliftIO m, Foldable f) => f a -> a -> m b -> m ()
+ Termonad.Prelude: forM :: (Traversable t, Monad m) => t a -> a -> m b -> m t b
+ Termonad.Prelude: forM_ :: (MonoFoldable mono, Applicative m) => mono -> Element mono -> m () -> m ()
+ Termonad.Prelude: for_ :: (MonoFoldable mono, Applicative f) => mono -> Element mono -> f b -> f ()
+ Termonad.Prelude: force :: NFData a => a -> a
+ Termonad.Prelude: forever :: Applicative f => f a -> f b
+ Termonad.Prelude: formatTime :: FormatTime t => TimeLocale -> String -> t -> String
+ Termonad.Prelude: freeSlotsTBChan :: () => TBChan a -> STM Int
+ Termonad.Prelude: freeSlotsTBMChan :: () => TBMChan a -> STM Int
+ Termonad.Prelude: freeSlotsTBMQueue :: () => TBMQueue a -> STM Int
+ Termonad.Prelude: fromByteVector :: SVector Word8 -> ByteString
+ Termonad.Prelude: fromChunks :: LazySequence lazy strict => [strict] -> lazy
+ Termonad.Prelude: fromEither :: (Exception e, MonadIO m) => Either e a -> m a
+ Termonad.Prelude: fromEitherIO :: (Exception e, MonadIO m) => IO Either e a -> m a
+ Termonad.Prelude: fromEitherM :: (Exception e, MonadIO m) => m Either e a -> m a
+ Termonad.Prelude: fromEnum :: Enum a => a -> Int
+ Termonad.Prelude: fromException :: Exception e => SomeException -> Maybe e
+ Termonad.Prelude: fromGregorian :: Integer -> Int -> Int -> Day
+ Termonad.Prelude: fromInteger :: Num a => Integer -> a
+ Termonad.Prelude: fromIntegral :: (Integral a, Num b) => a -> b
+ Termonad.Prelude: fromList :: IsSequence seq => [Element seq] -> seq
+ Termonad.Prelude: fromMaybe :: () => a -> Maybe a -> a
+ Termonad.Prelude: fromNonEmpty :: IsSequence seq => NonEmpty Element seq -> NonNull seq
+ Termonad.Prelude: fromNullable :: MonoFoldable mono => mono -> Maybe NonNull mono
+ Termonad.Prelude: fromRational :: Fractional a => Rational -> a
+ Termonad.Prelude: fromStrict :: LazySequence lazy strict => strict -> lazy
+ Termonad.Prelude: fromString :: IsString a => String -> a
+ Termonad.Prelude: fst :: () => (a, b) -> a
+ Termonad.Prelude: fullErrorType :: IOErrorType
+ Termonad.Prelude: getArgs :: MonadIO m => m [Text]
+ Termonad.Prelude: getChanContents :: MonadIO m => Chan a -> m [a]
+ Termonad.Prelude: getChar :: MonadIO m => m Char
+ Termonad.Prelude: getContents :: MonadIO m => m LText
+ Termonad.Prelude: getCurrentTime :: IO UTCTime
+ Termonad.Prelude: getLine :: MonadIO m => m Text
+ Termonad.Prelude: getMonotonicTime :: MonadIO m => m Double
+ Termonad.Prelude: group :: (IsSequence seq, Eq Element seq) => seq -> [seq]
+ Termonad.Prelude: groupAll :: (IsSequence seq, Eq Element seq) => seq -> [seq]
+ Termonad.Prelude: groupAllOn :: (IsSequence seq, Eq b) => Element seq -> b -> seq -> [seq]
+ Termonad.Prelude: groupBy :: IsSequence seq => Element seq -> Element seq -> Bool -> seq -> [seq]
+ Termonad.Prelude: guard :: Alternative f => Bool -> f ()
+ Termonad.Prelude: hClose :: MonadIO m => Handle -> m ()
+ Termonad.Prelude: hFileSize :: MonadIO m => Handle -> m Integer
+ Termonad.Prelude: hFlush :: MonadIO m => Handle -> m ()
+ Termonad.Prelude: hGetBuffering :: MonadIO m => Handle -> m BufferMode
+ Termonad.Prelude: hGetChunk :: MonadIO m => Handle -> m ByteString
+ Termonad.Prelude: hGetContents :: MonadIO m => Handle -> m ByteString
+ Termonad.Prelude: hGetEcho :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hIsClosed :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hIsEOF :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hIsOpen :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hIsReadable :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hIsSeekable :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hIsTerminalDevice :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hIsWritable :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hPut :: MonadIO m => Handle -> ByteString -> m ()
+ Termonad.Prelude: hReady :: MonadIO m => Handle -> m Bool
+ Termonad.Prelude: hSay :: MonadIO m => Handle -> Text -> m ()
+ Termonad.Prelude: hSayShow :: (MonadIO m, Show a) => Handle -> a -> m ()
+ Termonad.Prelude: hSayString :: MonadIO m => Handle -> String -> m ()
+ Termonad.Prelude: hSeek :: MonadIO m => Handle -> SeekMode -> Integer -> m ()
+ Termonad.Prelude: hSetBuffering :: MonadIO m => Handle -> BufferMode -> m ()
+ Termonad.Prelude: hSetEcho :: MonadIO m => Handle -> Bool -> m ()
+ Termonad.Prelude: hSetFileSize :: MonadIO m => Handle -> Integer -> m ()
+ Termonad.Prelude: hTell :: MonadIO m => Handle -> m Integer
+ Termonad.Prelude: hWaitForInput :: MonadIO m => Handle -> Int -> m Bool
+ Termonad.Prelude: handle :: (MonadUnliftIO m, Exception e) => e -> m a -> m a -> m a
+ Termonad.Prelude: handleAny :: MonadUnliftIO m => SomeException -> m a -> m a -> m a
+ Termonad.Prelude: handleAnyDeep :: (MonadUnliftIO m, NFData a) => SomeException -> m a -> m a -> m a
+ Termonad.Prelude: handleDeep :: (MonadUnliftIO m, Exception e, NFData a) => e -> m a -> m a -> m a
+ Termonad.Prelude: handleIO :: MonadUnliftIO m => IOException -> m a -> m a -> m a
+ Termonad.Prelude: handleJust :: (MonadUnliftIO m, Exception e) => e -> Maybe b -> b -> m a -> m a -> m a
+ Termonad.Prelude: hash :: Hashable a => a -> Int
+ Termonad.Prelude: hashNub :: (Hashable a, Eq a) => [a] -> [a]
+ Termonad.Prelude: hashWithSalt :: Hashable a => Int -> a -> Int
+ Termonad.Prelude: head :: MonoFoldable mono => NonNull mono -> Element mono
+ Termonad.Prelude: headEx :: MonoFoldable mono => mono -> Element mono
+ Termonad.Prelude: headMay :: MonoFoldable mono => mono -> Maybe Element mono
+ Termonad.Prelude: id :: Category cat => cat a a
+ Termonad.Prelude: illegalOperationErrorType :: IOErrorType
+ Termonad.Prelude: impureNonNull :: MonoFoldable mono => mono -> NonNull mono
+ Termonad.Prelude: impureThrow :: Exception e => e -> a
+ Termonad.Prelude: index :: IsSequence seq => seq -> Index seq -> Maybe Element seq
+ Termonad.Prelude: indexEx :: IsSequence seq => seq -> Index seq -> Element seq
+ Termonad.Prelude: infixl 0 `on`
+ Termonad.Prelude: infixl 1 <&>
+ Termonad.Prelude: infixl 4 <**>
+ Termonad.Prelude: infixl 9 \\
+ Termonad.Prelude: infixr 0 $!!
+ Termonad.Prelude: infixr 1 >=>
+ Termonad.Prelude: infixr 2 <||>
+ Termonad.Prelude: infixr 3 <&&>
+ Termonad.Prelude: infixr 5 ++
+ Termonad.Prelude: infixr 7 <.>
+ Termonad.Prelude: infixr 8 ^^
+ Termonad.Prelude: infixr 9 .
+ Termonad.Prelude: init :: IsSequence seq => NonNull seq -> seq
+ Termonad.Prelude: initDef :: IsSequence seq => seq -> seq
+ Termonad.Prelude: initEx :: IsSequence seq => seq -> seq
+ Termonad.Prelude: initMay :: IsSequence seq => seq -> Maybe seq
+ Termonad.Prelude: insertLookupWithKey :: IsMap map => ContainerKey map -> MapValue map -> MapValue map -> MapValue map -> ContainerKey map -> MapValue map -> map -> (Maybe MapValue map, map)
+ Termonad.Prelude: insertMap :: IsMap map => ContainerKey map -> MapValue map -> map -> map
+ Termonad.Prelude: insertSet :: IsSet set => Element set -> set -> set
+ Termonad.Prelude: insertWith :: IsMap map => MapValue map -> MapValue map -> MapValue map -> ContainerKey map -> MapValue map -> map -> map
+ Termonad.Prelude: insertWithKey :: IsMap map => ContainerKey map -> MapValue map -> MapValue map -> MapValue map -> ContainerKey map -> MapValue map -> map -> map
+ Termonad.Prelude: interact :: MonadIO m => LText -> LText -> m ()
+ Termonad.Prelude: intercalate :: (MonoFoldable mono, Monoid Element mono) => Element mono -> mono -> Element mono
+ Termonad.Prelude: intersect :: SetContainer a => a -> a -> a
+ Termonad.Prelude: intersection :: SetContainer set => set -> set -> set
+ Termonad.Prelude: intersectionMap :: PolyMap map => map value1 -> map value2 -> map value1
+ Termonad.Prelude: intersectionWithMap :: PolyMap map => value1 -> value2 -> value3 -> map value1 -> map value2 -> map value3
+ Termonad.Prelude: intersperse :: SemiSequence seq => Element seq -> seq -> seq
+ Termonad.Prelude: ioError :: () => IOError -> IO a
+ Termonad.Prelude: ioeGetErrorString :: IOError -> String
+ Termonad.Prelude: ioeGetErrorType :: IOError -> IOErrorType
+ Termonad.Prelude: ioeGetFileName :: IOError -> Maybe FilePath
+ Termonad.Prelude: ioeGetHandle :: IOError -> Maybe Handle
+ Termonad.Prelude: ioeGetLocation :: IOError -> String
+ Termonad.Prelude: ioeSetErrorString :: IOError -> String -> IOError
+ Termonad.Prelude: ioeSetErrorType :: IOError -> IOErrorType -> IOError
+ Termonad.Prelude: ioeSetFileName :: IOError -> FilePath -> IOError
+ Termonad.Prelude: ioeSetHandle :: IOError -> Handle -> IOError
+ Termonad.Prelude: ioeSetLocation :: IOError -> String -> IOError
+ Termonad.Prelude: isAlreadyExistsError :: IOError -> Bool
+ Termonad.Prelude: isAlreadyExistsErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: isAlreadyInUseError :: IOError -> Bool
+ Termonad.Prelude: isAlreadyInUseErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: isAsyncException :: Exception e => e -> Bool
+ Termonad.Prelude: isClosedTBMChan :: () => TBMChan a -> STM Bool
+ Termonad.Prelude: isClosedTBMQueue :: () => TBMQueue a -> STM Bool
+ Termonad.Prelude: isClosedTMChan :: () => TMChan a -> STM Bool
+ Termonad.Prelude: isClosedTMQueue :: () => TMQueue a -> STM Bool
+ Termonad.Prelude: isDenormalized :: RealFloat a => a -> Bool
+ Termonad.Prelude: isDoesNotExistError :: IOError -> Bool
+ Termonad.Prelude: isDoesNotExistErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: isEOFError :: IOError -> Bool
+ Termonad.Prelude: isEOFErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: isEmptyMVar :: MonadIO m => MVar a -> m Bool
+ Termonad.Prelude: isEmptyTBChan :: () => TBChan a -> STM Bool
+ Termonad.Prelude: isEmptyTBMChan :: () => TBMChan a -> STM Bool
+ Termonad.Prelude: isEmptyTBMQueue :: () => TBMQueue a -> STM Bool
+ Termonad.Prelude: isEmptyTBQueue :: () => TBQueue a -> STM Bool
+ Termonad.Prelude: isEmptyTChan :: () => TChan a -> STM Bool
+ Termonad.Prelude: isEmptyTMChan :: () => TMChan a -> STM Bool
+ Termonad.Prelude: isEmptyTMQueue :: () => TMQueue a -> STM Bool
+ Termonad.Prelude: isEmptyTMVar :: () => TMVar a -> STM Bool
+ Termonad.Prelude: isEmptyTQueue :: () => TQueue a -> STM Bool
+ Termonad.Prelude: isFullError :: IOError -> Bool
+ Termonad.Prelude: isFullErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: isFullTBChan :: () => TBChan a -> STM Bool
+ Termonad.Prelude: isFullTBMChan :: () => TBMChan a -> STM Bool
+ Termonad.Prelude: isFullTBMQueue :: () => TBMQueue a -> STM Bool
+ Termonad.Prelude: isFullTBQueue :: () => TBQueue a -> STM Bool
+ Termonad.Prelude: isIEEE :: RealFloat a => a -> Bool
+ Termonad.Prelude: isIllegalOperation :: IOError -> Bool
+ Termonad.Prelude: isIllegalOperationErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: isInfinite :: RealFloat a => a -> Bool
+ Termonad.Prelude: isInfixOf :: (IsSequence seq, Eq Element seq) => seq -> seq -> Bool
+ Termonad.Prelude: isJust :: () => Maybe a -> Bool
+ Termonad.Prelude: isNaN :: RealFloat a => a -> Bool
+ Termonad.Prelude: isNegativeZero :: RealFloat a => a -> Bool
+ Termonad.Prelude: isNothing :: () => Maybe a -> Bool
+ Termonad.Prelude: isPermissionError :: IOError -> Bool
+ Termonad.Prelude: isPermissionErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: isPrefixOf :: (IsSequence seq, Eq Element seq) => seq -> seq -> Bool
+ Termonad.Prelude: isSuffixOf :: (IsSequence seq, Eq Element seq) => seq -> seq -> Bool
+ Termonad.Prelude: isSyncException :: Exception e => e -> Bool
+ Termonad.Prelude: isUserError :: IOError -> Bool
+ Termonad.Prelude: isUserErrorType :: IOErrorType -> Bool
+ Termonad.Prelude: join :: Monad m => m m a -> m a
+ Termonad.Prelude: keys :: SetContainer set => set -> [ContainerKey set]
+ Termonad.Prelude: keysSet :: HasKeysSet set => set -> KeySet set
+ Termonad.Prelude: last :: MonoFoldable mono => NonNull mono -> Element mono
+ Termonad.Prelude: lastEx :: MonoFoldable mono => mono -> Element mono
+ Termonad.Prelude: lastMay :: MonoFoldable mono => mono -> Maybe Element mono
+ Termonad.Prelude: lefts :: () => [Either a b] -> [a]
+ Termonad.Prelude: length :: MonoFoldable mono => mono -> Int
+ Termonad.Prelude: length64 :: MonoFoldable mono => mono -> Int64
+ Termonad.Prelude: lengthIndex :: IsSequence seq => seq -> Index seq
+ Termonad.Prelude: lift :: (MonadTrans t, Monad m) => m a -> t m a
+ Termonad.Prelude: liftA :: Applicative f => a -> b -> f a -> f b
+ Termonad.Prelude: liftA2 :: Applicative f => a -> b -> c -> f a -> f b -> f c
+ Termonad.Prelude: liftA3 :: Applicative f => a -> b -> c -> d -> f a -> f b -> f c -> f d
+ Termonad.Prelude: liftIO :: MonadIO m => IO a -> m a
+ Termonad.Prelude: liftM :: Monad m => a1 -> r -> m a1 -> m r
+ Termonad.Prelude: liftM2 :: Monad m => a1 -> a2 -> r -> m a1 -> m a2 -> m r
+ Termonad.Prelude: liftM3 :: Monad m => a1 -> a2 -> a3 -> r -> m a1 -> m a2 -> m a3 -> m r
+ Termonad.Prelude: liftM4 :: Monad m => a1 -> a2 -> a3 -> a4 -> r -> m a1 -> m a2 -> m a3 -> m a4 -> m r
+ Termonad.Prelude: liftM5 :: Monad m => a1 -> a2 -> a3 -> a4 -> a5 -> r -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
+ Termonad.Prelude: lines :: Textual t => t -> [t]
+ Termonad.Prelude: link :: MonadIO m => Async a -> m ()
+ Termonad.Prelude: link2 :: MonadIO m => Async a -> Async b -> m ()
+ Termonad.Prelude: link2Async :: MonadIO m => Async a -> Async b -> m ()
+ Termonad.Prelude: linkAsync :: MonadIO m => Async a -> m ()
+ Termonad.Prelude: listToMaybe :: () => [a] -> Maybe a
+ Termonad.Prelude: log :: Floating a => a -> a
+ Termonad.Prelude: logBase :: Floating a => a -> a -> a
+ Termonad.Prelude: lookup :: IsMap map => ContainerKey map -> map -> Maybe MapValue map
+ Termonad.Prelude: many :: Alternative f => f a -> f [a]
+ Termonad.Prelude: map :: Functor f => a -> b -> f a -> f b
+ Termonad.Prelude: mapConcurrently :: (MonadUnliftIO m, Traversable t) => a -> m b -> t a -> m t b
+ Termonad.Prelude: mapConcurrently_ :: (MonadUnliftIO m, Foldable f) => a -> m b -> f a -> m ()
+ Termonad.Prelude: mapFromList :: IsMap map => [(ContainerKey map, MapValue map)] -> map
+ Termonad.Prelude: mapKeysWith :: (BiPolyMap map, BPMKeyConstraint map k1, BPMKeyConstraint map k2) => v -> v -> v -> k1 -> k2 -> map k1 v -> map k2 v
+ Termonad.Prelude: mapM :: (Traversable t, Monad m) => a -> m b -> t a -> m t b
+ Termonad.Prelude: mapM_ :: (MonoFoldable mono, Applicative m) => Element mono -> m () -> mono -> m ()
+ Termonad.Prelude: mapMaybe :: () => a -> Maybe b -> [a] -> [b]
+ Termonad.Prelude: mapNonNull :: (Functor f, MonoFoldable f b) => a -> b -> NonNull f a -> NonNull f b
+ Termonad.Prelude: mapToList :: IsMap map => map -> [(ContainerKey map, MapValue map)]
+ Termonad.Prelude: mapWithKey :: IsMap map => ContainerKey map -> MapValue map -> MapValue map -> map -> map
+ Termonad.Prelude: mappend :: Monoid a => a -> a -> a
+ Termonad.Prelude: mask :: MonadUnliftIO m => forall a. () => m a -> m a -> m b -> m b
+ Termonad.Prelude: mask_ :: MonadUnliftIO m => m a -> m a
+ Termonad.Prelude: max :: Ord a => a -> a -> a
+ Termonad.Prelude: maxBound :: Bounded a => a
+ Termonad.Prelude: maximum :: (MonoFoldable mono, Ord Element mono) => NonNull mono -> Element mono
+ Termonad.Prelude: maximumBy :: MonoFoldable mono => Element mono -> Element mono -> Ordering -> NonNull mono -> Element mono
+ Termonad.Prelude: maximumByEx :: MonoFoldable mono => Element mono -> Element mono -> Ordering -> mono -> Element mono
+ Termonad.Prelude: maximumByMay :: MonoFoldable mono => Element mono -> Element mono -> Ordering -> mono -> Maybe Element mono
+ Termonad.Prelude: maximumEx :: (MonoFoldable mono, Ord Element mono) => mono -> Element mono
+ Termonad.Prelude: maximumMay :: (MonoFoldable mono, Ord Element mono) => mono -> Maybe Element mono
+ Termonad.Prelude: maybe :: () => b -> a -> b -> Maybe a -> b
+ Termonad.Prelude: maybeToList :: () => Maybe a -> [a]
+ Termonad.Prelude: mconcat :: Monoid a => [a] -> a
+ Termonad.Prelude: member :: SetContainer set => ContainerKey set -> set -> Bool
+ Termonad.Prelude: memoizeMVar :: MonadUnliftIO m => m a -> m Memoized a
+ Termonad.Prelude: memoizeRef :: MonadUnliftIO m => m a -> m Memoized a
+ Termonad.Prelude: mempty :: Monoid a => a
+ Termonad.Prelude: min :: Ord a => a -> a -> a
+ Termonad.Prelude: minBound :: Bounded a => a
+ Termonad.Prelude: minimum :: (MonoFoldable mono, Ord Element mono) => NonNull mono -> Element mono
+ Termonad.Prelude: minimumBy :: MonoFoldable mono => Element mono -> Element mono -> Ordering -> NonNull mono -> Element mono
+ Termonad.Prelude: minimumByEx :: MonoFoldable mono => Element mono -> Element mono -> Ordering -> mono -> Element mono
+ Termonad.Prelude: minimumByMay :: MonoFoldable mono => Element mono -> Element mono -> Ordering -> mono -> Maybe Element mono
+ Termonad.Prelude: minimumEx :: (MonoFoldable mono, Ord Element mono) => mono -> Element mono
+ Termonad.Prelude: minimumMay :: (MonoFoldable mono, Ord Element mono) => mono -> Maybe Element mono
+ Termonad.Prelude: mkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath -> IOError
+ Termonad.Prelude: mkWeakIORef :: MonadUnliftIO m => IORef a -> m () -> m Weak IORef a
+ Termonad.Prelude: mkWeakMVar :: MonadUnliftIO m => MVar a -> m () -> m Weak MVar a
+ Termonad.Prelude: mkWeakTMVar :: MonadUnliftIO m => TMVar a -> m () -> m Weak TMVar a
+ Termonad.Prelude: mkWeakTVar :: MonadUnliftIO m => TVar a -> m () -> m Weak TVar a
+ Termonad.Prelude: mod :: Integral a => a -> a -> a
+ Termonad.Prelude: modifyIOError :: () => IOError -> IOError -> IO a -> IO a
+ Termonad.Prelude: modifyIORef :: MonadIO m => IORef a -> a -> a -> m ()
+ Termonad.Prelude: modifyIORef' :: MonadIO m => IORef a -> a -> a -> m ()
+ Termonad.Prelude: modifyMVar :: MonadUnliftIO m => MVar a -> a -> m (a, b) -> m b
+ Termonad.Prelude: modifyMVarMasked :: MonadUnliftIO m => MVar a -> a -> m (a, b) -> m b
+ Termonad.Prelude: modifyMVarMasked_ :: MonadUnliftIO m => MVar a -> a -> m a -> m ()
+ Termonad.Prelude: modifyMVar_ :: MonadUnliftIO m => MVar a -> a -> m a -> m ()
+ Termonad.Prelude: modifyMutVar :: PrimMonad m => MutVar PrimState m a -> a -> a -> m ()
+ Termonad.Prelude: modifyMutVar' :: PrimMonad m => MutVar PrimState m a -> a -> a -> m ()
+ Termonad.Prelude: modifyRef :: (MutableRef c, PrimMonad m, PrimState m ~ MCState c) => c -> RefElement c -> RefElement c -> m ()
+ Termonad.Prelude: modifyRef' :: (MutableRef c, PrimMonad m, PrimState m ~ MCState c) => c -> RefElement c -> RefElement c -> m ()
+ Termonad.Prelude: modifyTVar :: () => TVar a -> a -> a -> STM ()
+ Termonad.Prelude: modifyTVar' :: () => TVar a -> a -> a -> STM ()
+ Termonad.Prelude: mplus :: MonadPlus m => m a -> m a -> m a
+ Termonad.Prelude: mzero :: MonadPlus m => m a
+ Termonad.Prelude: nReplicate :: IsSequence seq => Index seq -> Element seq -> NonNull seq
+ Termonad.Prelude: ncons :: SemiSequence seq => Element seq -> seq -> NonNull seq
+ Termonad.Prelude: negate :: Num a => a -> a
+ Termonad.Prelude: newBroadcastTChan :: () => STM TChan a
+ Termonad.Prelude: newBroadcastTChanIO :: MonadIO m => m TChan a
+ Termonad.Prelude: newBroadcastTMChan :: () => STM TMChan a
+ Termonad.Prelude: newBroadcastTMChanIO :: () => IO TMChan a
+ Termonad.Prelude: newChan :: MonadIO m => m Chan a
+ Termonad.Prelude: newColl :: (MutableCollection c, PrimMonad m, PrimState m ~ MCState c) => m c
+ Termonad.Prelude: newEmptyMVar :: MonadIO m => m MVar a
+ Termonad.Prelude: newEmptyTMVar :: () => STM TMVar a
+ Termonad.Prelude: newEmptyTMVarIO :: MonadIO m => m TMVar a
+ Termonad.Prelude: newIORef :: MonadIO m => a -> m IORef a
+ Termonad.Prelude: newMVar :: MonadIO m => a -> m MVar a
+ Termonad.Prelude: newMutVar :: PrimMonad m => a -> m MutVar PrimState m a
+ Termonad.Prelude: newRef :: (MutableRef c, PrimMonad m, PrimState m ~ MCState c) => RefElement c -> m c
+ Termonad.Prelude: newTBChan :: () => Int -> STM TBChan a
+ Termonad.Prelude: newTBChanIO :: () => Int -> IO TBChan a
+ Termonad.Prelude: newTBMChan :: () => Int -> STM TBMChan a
+ Termonad.Prelude: newTBMChanIO :: () => Int -> IO TBMChan a
+ Termonad.Prelude: newTBMQueue :: () => Int -> STM TBMQueue a
+ Termonad.Prelude: newTBMQueueIO :: () => Int -> IO TBMQueue a
+ Termonad.Prelude: newTBQueue :: () => Int -> STM TBQueue a
+ Termonad.Prelude: newTBQueueIO :: MonadIO m => Int -> m TBQueue a
+ Termonad.Prelude: newTChan :: () => STM TChan a
+ Termonad.Prelude: newTChanIO :: MonadIO m => m TChan a
+ Termonad.Prelude: newTMChan :: () => STM TMChan a
+ Termonad.Prelude: newTMChanIO :: () => IO TMChan a
+ Termonad.Prelude: newTMQueue :: () => STM TMQueue a
+ Termonad.Prelude: newTMQueueIO :: () => IO TMQueue a
+ Termonad.Prelude: newTMVar :: () => a -> STM TMVar a
+ Termonad.Prelude: newTMVarIO :: MonadIO m => a -> m TMVar a
+ Termonad.Prelude: newTQueue :: () => STM TQueue a
+ Termonad.Prelude: newTQueueIO :: MonadIO m => m TQueue a
+ Termonad.Prelude: newTVar :: () => a -> STM TVar a
+ Termonad.Prelude: newTVarIO :: MonadIO m => a -> m TVar a
+ Termonad.Prelude: newtype ReaderT r (m :: k -> *) (a :: k) :: forall k. () => * -> k -> * -> k -> *
+ Termonad.Prelude: newtype Concurrently (m :: * -> *) a
+ Termonad.Prelude: newtype Day
+ Termonad.Prelude: newtype Down a
+ Termonad.Prelude: newtype Identity a
+ Termonad.Prelude: newtype UnliftIO (m :: * -> *)
+ Termonad.Prelude: nfilter :: IsSequence seq => Element seq -> Bool -> NonNull seq -> seq
+ Termonad.Prelude: nfilterM :: (Monad m, IsSequence seq) => Element seq -> m Bool -> NonNull seq -> m seq
+ Termonad.Prelude: nonNull :: MonoFoldable mono => mono -> NonNull mono
+ Termonad.Prelude: not :: Bool -> Bool
+ Termonad.Prelude: notElem :: (MonoFoldable mono, Eq Element mono) => Element mono -> mono -> Bool
+ Termonad.Prelude: notMember :: SetContainer set => ContainerKey set -> set -> Bool
+ Termonad.Prelude: null :: MonoFoldable mono => mono -> Bool
+ Termonad.Prelude: nuncons :: IsSequence seq => NonNull seq -> (Element seq, Maybe NonNull seq)
+ Termonad.Prelude: oall :: MonoFoldable mono => Element mono -> Bool -> mono -> Bool
+ Termonad.Prelude: oand :: (Element mono ~ Bool, MonoFoldable mono) => mono -> Bool
+ Termonad.Prelude: oany :: MonoFoldable mono => Element mono -> Bool -> mono -> Bool
+ Termonad.Prelude: ocompareLength :: (MonoFoldable mono, Integral i) => mono -> i -> Ordering
+ Termonad.Prelude: oconcat :: (MonoFoldable mono, Monoid Element mono) => mono -> Element mono
+ Termonad.Prelude: oconcatMap :: (MonoFoldable mono, Monoid m) => Element mono -> m -> mono -> m
+ Termonad.Prelude: odd :: Integral a => a -> Bool
+ Termonad.Prelude: oelem :: MonoFoldable mono => Element mono -> mono -> Bool
+ Termonad.Prelude: oextend :: MonoComonad mono => mono -> Element mono -> mono -> mono
+ Termonad.Prelude: oextract :: MonoComonad mono => mono -> Element mono
+ Termonad.Prelude: ofold :: (MonoFoldable mono, Monoid Element mono) => mono -> Element mono
+ Termonad.Prelude: ofold1 :: (MonoFoldable mono, Semigroup Element mono) => NonNull mono -> Element mono
+ Termonad.Prelude: ofoldM :: (MonoFoldable mono, Monad m) => a -> Element mono -> m a -> a -> mono -> m a
+ Termonad.Prelude: ofoldMUnwrap :: (Monad m, MonoFoldable mono) => x -> Element mono -> m x -> m x -> x -> m b -> mono -> m b
+ Termonad.Prelude: ofoldMap :: (MonoFoldable mono, Monoid m) => Element mono -> m -> mono -> m
+ Termonad.Prelude: ofoldMap1 :: (MonoFoldable mono, Semigroup m) => Element mono -> m -> NonNull mono -> m
+ Termonad.Prelude: ofoldMap1Ex :: (MonoFoldable mono, Semigroup m) => Element mono -> m -> mono -> m
+ Termonad.Prelude: ofoldl' :: MonoFoldable mono => a -> Element mono -> a -> a -> mono -> a
+ Termonad.Prelude: ofoldl1' :: MonoFoldable mono => Element mono -> Element mono -> Element mono -> NonNull mono -> Element mono
+ Termonad.Prelude: ofoldl1Ex' :: MonoFoldable mono => Element mono -> Element mono -> Element mono -> mono -> Element mono
+ Termonad.Prelude: ofoldlM :: (MonoFoldable mono, Monad m) => a -> Element mono -> m a -> a -> mono -> m a
+ Termonad.Prelude: ofoldlUnwrap :: MonoFoldable mono => x -> Element mono -> x -> x -> x -> b -> mono -> b
+ Termonad.Prelude: ofoldr :: MonoFoldable mono => Element mono -> b -> b -> b -> mono -> b
+ Termonad.Prelude: ofoldr1 :: MonoFoldable mono => Element mono -> Element mono -> Element mono -> NonNull mono -> Element mono
+ Termonad.Prelude: ofoldr1Ex :: MonoFoldable mono => Element mono -> Element mono -> Element mono -> mono -> Element mono
+ Termonad.Prelude: ofor :: (MonoTraversable mono, Applicative f) => mono -> Element mono -> f Element mono -> f mono
+ Termonad.Prelude: oforM :: (MonoTraversable mono, Applicative f) => mono -> Element mono -> f Element mono -> f mono
+ Termonad.Prelude: oforM_ :: (MonoFoldable mono, Applicative m) => mono -> Element mono -> m () -> m ()
+ Termonad.Prelude: ofor_ :: (MonoFoldable mono, Applicative f) => mono -> Element mono -> f b -> f ()
+ Termonad.Prelude: ointercalate :: (MonoFoldable mono, Monoid Element mono) => Element mono -> mono -> Element mono
+ Termonad.Prelude: olength :: MonoFoldable mono => mono -> Int
+ Termonad.Prelude: olength64 :: MonoFoldable mono => mono -> Int64
+ Termonad.Prelude: omap :: MonoFunctor mono => Element mono -> Element mono -> mono -> mono
+ Termonad.Prelude: omapKeysWith :: IsMap map => MapValue map -> MapValue map -> MapValue map -> ContainerKey map -> ContainerKey map -> map -> map
+ Termonad.Prelude: omapM :: (MonoTraversable mono, Applicative m) => Element mono -> m Element mono -> mono -> m mono
+ Termonad.Prelude: omapM_ :: (MonoFoldable mono, Applicative m) => Element mono -> m () -> mono -> m ()
+ Termonad.Prelude: on :: () => b -> b -> c -> a -> b -> a -> a -> c
+ Termonad.Prelude: onException :: MonadUnliftIO m => m a -> m b -> m a
+ Termonad.Prelude: onotElem :: MonoFoldable mono => Element mono -> mono -> Bool
+ Termonad.Prelude: onull :: MonoFoldable mono => mono -> Bool
+ Termonad.Prelude: oor :: (Element mono ~ Bool, MonoFoldable mono) => mono -> Bool
+ Termonad.Prelude: opoint :: MonoPointed mono => Element mono -> mono
+ Termonad.Prelude: oproduct :: (MonoFoldable mono, Num Element mono) => mono -> Element mono
+ Termonad.Prelude: optional :: Alternative f => f a -> f Maybe a
+ Termonad.Prelude: or :: (MonoFoldable mono, Element mono ~ Bool) => mono -> Bool
+ Termonad.Prelude: orElseSTM :: () => STM a -> STM a -> STM a
+ Termonad.Prelude: ordNub :: Ord a => [a] -> [a]
+ Termonad.Prelude: ordNubBy :: Ord b => a -> b -> a -> a -> Bool -> [a] -> [a]
+ Termonad.Prelude: osequence_ :: (Applicative m, MonoFoldable mono, Element mono ~ m ()) => mono -> m ()
+ Termonad.Prelude: osum :: (MonoFoldable mono, Num Element mono) => mono -> Element mono
+ Termonad.Prelude: otherwise :: Bool
+ Termonad.Prelude: otoList :: MonoFoldable mono => mono -> [Element mono]
+ Termonad.Prelude: otraverse :: (MonoTraversable mono, Applicative f) => Element mono -> f Element mono -> mono -> f mono
+ Termonad.Prelude: otraverse_ :: (MonoFoldable mono, Applicative f) => Element mono -> f b -> mono -> f ()
+ Termonad.Prelude: ounzip :: MonoZip mono => [(Element mono, Element mono)] -> (mono, mono)
+ Termonad.Prelude: ozip :: MonoZip mono => mono -> mono -> [(Element mono, Element mono)]
+ Termonad.Prelude: ozipWith :: MonoZip mono => Element mono -> Element mono -> Element mono -> mono -> mono -> mono
+ Termonad.Prelude: pack :: IsSequence seq => [Element seq] -> seq
+ Termonad.Prelude: parseTime :: ParseTime t => TimeLocale -> String -> String -> Maybe t
+ Termonad.Prelude: parseTimeM :: (Monad m, ParseTime t) => Bool -> TimeLocale -> String -> String -> m t
+ Termonad.Prelude: partition :: IsSequence seq => Element seq -> Bool -> seq -> (seq, seq)
+ Termonad.Prelude: partitionEithers :: () => [Either a b] -> ([a], [b])
+ Termonad.Prelude: peekTBChan :: () => TBChan a -> STM a
+ Termonad.Prelude: peekTBMChan :: () => TBMChan a -> STM Maybe a
+ Termonad.Prelude: peekTBMQueue :: () => TBMQueue a -> STM Maybe a
+ Termonad.Prelude: peekTBQueue :: () => TBQueue a -> STM a
+ Termonad.Prelude: peekTChan :: () => TChan a -> STM a
+ Termonad.Prelude: peekTMChan :: () => TMChan a -> STM Maybe a
+ Termonad.Prelude: peekTMQueue :: () => TMQueue a -> STM Maybe a
+ Termonad.Prelude: peekTQueue :: () => TQueue a -> STM a
+ Termonad.Prelude: permissionErrorType :: IOErrorType
+ Termonad.Prelude: permutations :: IsSequence seq => seq -> [seq]
+ Termonad.Prelude: pi :: Floating a => a
+ Termonad.Prelude: point :: MonoPointed mono => Element mono -> mono
+ Termonad.Prelude: poll :: MonadIO m => Async a -> m Maybe Either SomeException a
+ Termonad.Prelude: pollAsync :: MonadIO m => Async a -> m Maybe Either SomeException a
+ Termonad.Prelude: pollSTM :: () => Async a -> STM Maybe Either SomeException a
+ Termonad.Prelude: popBack :: (MutablePopBack c, PrimMonad m, PrimState m ~ MCState c) => c -> m Maybe CollElement c
+ Termonad.Prelude: popFront :: (MutablePopFront c, PrimMonad m, PrimState m ~ MCState c) => c -> m Maybe CollElement c
+ Termonad.Prelude: pred :: Enum a => a -> a
+ Termonad.Prelude: primToIO :: (PrimBase m, PrimState m ~ RealWorld) => m a -> IO a
+ Termonad.Prelude: primToPrim :: (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) => m1 a -> m2 a
+ Termonad.Prelude: primToST :: PrimBase m => m a -> ST PrimState m a
+ Termonad.Prelude: print :: (Show a, MonadIO m) => a -> m ()
+ Termonad.Prelude: product :: (MonoFoldable mono, Num Element mono) => mono -> Element mono
+ Termonad.Prelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
+ Termonad.Prelude: pure :: Applicative f => a -> f a
+ Termonad.Prelude: pureTry :: () => a -> Either SomeException a
+ Termonad.Prelude: pureTryDeep :: NFData a => a -> Either SomeException a
+ Termonad.Prelude: pushBack :: (MutablePushBack c, PrimMonad m, PrimState m ~ MCState c) => c -> CollElement c -> m ()
+ Termonad.Prelude: pushFront :: (MutablePushFront c, PrimMonad m, PrimState m ~ MCState c) => c -> CollElement c -> m ()
+ Termonad.Prelude: putChar :: MonadIO m => Char -> m ()
+ Termonad.Prelude: putMVar :: MonadIO m => MVar a -> a -> m ()
+ Termonad.Prelude: putStr :: MonadIO m => Text -> m ()
+ Termonad.Prelude: putStrLn :: MonadIO m => Text -> m ()
+ Termonad.Prelude: putTMVar :: () => TMVar a -> a -> STM ()
+ Termonad.Prelude: quot :: Integral a => a -> a -> a
+ Termonad.Prelude: quotRem :: Integral a => a -> a -> (a, a)
+ Termonad.Prelude: race :: MonadUnliftIO m => m a -> m b -> m Either a b
+ Termonad.Prelude: race_ :: MonadUnliftIO m => m a -> m b -> m ()
+ Termonad.Prelude: readChan :: MonadIO m => Chan a -> m a
+ Termonad.Prelude: readFile :: MonadIO m => FilePath -> m ByteString
+ Termonad.Prelude: readFileUtf8 :: MonadIO m => FilePath -> m Text
+ Termonad.Prelude: readIORef :: MonadIO m => IORef a -> m a
+ Termonad.Prelude: readMVar :: MonadIO m => MVar a -> m a
+ Termonad.Prelude: readMay :: (Element c ~ Char, MonoFoldable c, Read a) => c -> Maybe a
+ Termonad.Prelude: readMutVar :: PrimMonad m => MutVar PrimState m a -> m a
+ Termonad.Prelude: readRef :: (MutableRef c, PrimMonad m, PrimState m ~ MCState c) => c -> m RefElement c
+ Termonad.Prelude: readTBChan :: () => TBChan a -> STM a
+ Termonad.Prelude: readTBMChan :: () => TBMChan a -> STM Maybe a
+ Termonad.Prelude: readTBMQueue :: () => TBMQueue a -> STM Maybe a
+ Termonad.Prelude: readTBQueue :: () => TBQueue a -> STM a
+ Termonad.Prelude: readTChan :: () => TChan a -> STM a
+ Termonad.Prelude: readTMChan :: () => TMChan a -> STM Maybe a
+ Termonad.Prelude: readTMQueue :: () => TMQueue a -> STM Maybe a
+ Termonad.Prelude: readTMVar :: () => TMVar a -> STM a
+ Termonad.Prelude: readTQueue :: () => TQueue a -> STM a
+ Termonad.Prelude: readTVar :: () => TVar a -> STM a
+ Termonad.Prelude: readTVarIO :: MonadIO m => TVar a -> m a
+ Termonad.Prelude: realToFrac :: (Real a, Fractional b) => a -> b
+ Termonad.Prelude: recip :: Fractional a => a -> a
+ Termonad.Prelude: registerDelay :: MonadIO m => Int -> m TVar Bool
+ Termonad.Prelude: rem :: Integral a => a -> a -> a
+ Termonad.Prelude: repack :: (MonoFoldable a, IsSequence b, Element a ~ Element b) => a -> b
+ Termonad.Prelude: repeat :: () => a -> [a]
+ Termonad.Prelude: replaceElem :: (MonoFunctor mono, Eq Element mono) => Element mono -> Element mono -> mono -> mono
+ Termonad.Prelude: replaceElemLazyText :: Char -> Char -> Text -> Text
+ Termonad.Prelude: replaceElemStrictText :: Char -> Char -> Text -> Text
+ Termonad.Prelude: replaceSeq :: (IsSequence seq, Eq Element seq) => seq -> seq -> seq -> seq
+ Termonad.Prelude: replaceSeqLazyText :: Text -> Text -> Text -> Text
+ Termonad.Prelude: replaceSeqStrictText :: Text -> Text -> Text -> Text
+ Termonad.Prelude: replicate :: IsSequence seq => Index seq -> Element seq -> seq
+ Termonad.Prelude: replicateConcurrently :: MonadUnliftIO m => Int -> m a -> m [a]
+ Termonad.Prelude: replicateConcurrently_ :: MonadUnliftIO m => Int -> m a -> m ()
+ Termonad.Prelude: replicateM :: (IsSequence seq, Monad m) => Index seq -> m Element seq -> m seq
+ Termonad.Prelude: replicateM_ :: Applicative m => Int -> m a -> m ()
+ Termonad.Prelude: retrySTM :: () => STM a
+ Termonad.Prelude: return :: Monad m => a -> m a
+ Termonad.Prelude: reverse :: SemiSequence seq => seq -> seq
+ Termonad.Prelude: rights :: () => [Either a b] -> [b]
+ Termonad.Prelude: rnf :: NFData a => a -> ()
+ Termonad.Prelude: round :: (RealFrac a, Integral b) => a -> b
+ Termonad.Prelude: runMemoized :: MonadIO m => Memoized a -> m a
+ Termonad.Prelude: say :: MonadIO m => Text -> m ()
+ Termonad.Prelude: sayErr :: MonadIO m => Text -> m ()
+ Termonad.Prelude: sayErrShow :: (MonadIO m, Show a) => a -> m ()
+ Termonad.Prelude: sayErrString :: MonadIO m => String -> m ()
+ Termonad.Prelude: sayShow :: (MonadIO m, Show a) => a -> m ()
+ Termonad.Prelude: sayString :: MonadIO m => String -> m ()
+ Termonad.Prelude: scaleFloat :: RealFloat a => Int -> a -> a
+ Termonad.Prelude: sconcat :: Semigroup a => NonEmpty a -> a
+ Termonad.Prelude: second :: Bifunctor p => b -> c -> p a b -> p a c
+ Termonad.Prelude: seq :: () => a -> b -> b
+ Termonad.Prelude: sequence :: (Traversable t, Monad m) => t m a -> m t a
+ Termonad.Prelude: sequenceA :: (Traversable t, Applicative f) => t f a -> f t a
+ Termonad.Prelude: sequence_ :: (Applicative m, MonoFoldable mono, Element mono ~ m ()) => mono -> m ()
+ Termonad.Prelude: setFromList :: IsSet set => [Element set] -> set
+ Termonad.Prelude: setToList :: IsSet set => set -> [Element set]
+ Termonad.Prelude: show :: Show a => a -> String
+ Termonad.Prelude: showList :: Show a => [a] -> ShowS
+ Termonad.Prelude: showsPrec :: Show a => Int -> a -> ShowS
+ Termonad.Prelude: significand :: RealFloat a => a -> a
+ Termonad.Prelude: signum :: Num a => a -> a
+ Termonad.Prelude: sin :: Floating a => a -> a
+ Termonad.Prelude: singleton :: MonoPointed seq => Element seq -> seq
+ Termonad.Prelude: singletonMap :: IsMap map => ContainerKey map -> MapValue map -> map
+ Termonad.Prelude: singletonSet :: IsSet set => Element set -> set
+ Termonad.Prelude: sinh :: Floating a => a -> a
+ Termonad.Prelude: snd :: () => (a, b) -> b
+ Termonad.Prelude: snoc :: SemiSequence seq => seq -> Element seq -> seq
+ Termonad.Prelude: some :: Alternative f => f a -> f [a]
+ Termonad.Prelude: sort :: (SemiSequence seq, Ord Element seq) => seq -> seq
+ Termonad.Prelude: sortBy :: SemiSequence seq => Element seq -> Element seq -> Ordering -> seq -> seq
+ Termonad.Prelude: sortOn :: (Ord o, SemiSequence seq) => Element seq -> o -> seq -> seq
+ Termonad.Prelude: sortWith :: (Ord a, IsSequence c) => Element c -> a -> c -> c
+ Termonad.Prelude: span :: IsSequence seq => Element seq -> Bool -> seq -> (seq, seq)
+ Termonad.Prelude: splitAt :: IsSequence seq => Index seq -> seq -> (seq, seq)
+ Termonad.Prelude: splitElem :: (IsSequence seq, Eq Element seq) => Element seq -> seq -> [seq]
+ Termonad.Prelude: splitElemStrictBS :: Word8 -> ByteString -> [ByteString]
+ Termonad.Prelude: splitFirst :: IsSequence seq => NonNull seq -> (Element seq, seq)
+ Termonad.Prelude: splitSeq :: (IsSequence seq, Eq Element seq) => seq -> seq -> [seq]
+ Termonad.Prelude: splitSeqLazyBS :: Word8 -> ByteString -> [ByteString]
+ Termonad.Prelude: splitSeqLazyText :: Text -> Text -> [Text]
+ Termonad.Prelude: splitSeqStrictText :: Text -> Text -> [Text]
+ Termonad.Prelude: splitWhen :: IsSequence seq => Element seq -> Bool -> seq -> [seq]
+ Termonad.Prelude: sqrt :: Floating a => a -> a
+ Termonad.Prelude: stderr :: Handle
+ Termonad.Prelude: stdin :: Handle
+ Termonad.Prelude: stdout :: Handle
+ Termonad.Prelude: stimes :: (Semigroup a, Integral b) => b -> a -> a
+ Termonad.Prelude: stringException :: HasCallStack -> String -> StringException
+ Termonad.Prelude: stripPrefix :: (IsSequence seq, Eq Element seq) => seq -> seq -> Maybe seq
+ Termonad.Prelude: stripPrefixLazyBS :: ByteString -> ByteString -> Maybe ByteString
+ Termonad.Prelude: stripPrefixStrictBS :: ByteString -> ByteString -> Maybe ByteString
+ Termonad.Prelude: stripSuffix :: (IsSequence seq, Eq Element seq) => seq -> seq -> Maybe seq
+ Termonad.Prelude: stripSuffixLazyBS :: ByteString -> ByteString -> Maybe ByteString
+ Termonad.Prelude: stripSuffixStrictBS :: ByteString -> ByteString -> Maybe ByteString
+ Termonad.Prelude: subsequences :: IsSequence seq => seq -> [seq]
+ Termonad.Prelude: subtract :: Num a => a -> a -> a
+ Termonad.Prelude: succ :: Enum a => a -> a
+ Termonad.Prelude: sum :: (MonoFoldable mono, Num Element mono) => mono -> Element mono
+ Termonad.Prelude: swap :: () => (a, b) -> (b, a)
+ Termonad.Prelude: swapMVar :: MonadIO m => MVar a -> a -> m a
+ Termonad.Prelude: swapTMVar :: () => TMVar a -> a -> STM a
+ Termonad.Prelude: swapTVar :: () => TVar a -> a -> STM a
+ Termonad.Prelude: tail :: IsSequence seq => NonNull seq -> seq
+ Termonad.Prelude: tailDef :: IsSequence seq => seq -> seq
+ Termonad.Prelude: tailEx :: IsSequence seq => seq -> seq
+ Termonad.Prelude: tailMay :: IsSequence seq => seq -> Maybe seq
+ Termonad.Prelude: take :: IsSequence seq => Index seq -> seq -> seq
+ Termonad.Prelude: takeMVar :: MonadIO m => MVar a -> m a
+ Termonad.Prelude: takeTMVar :: () => TMVar a -> STM a
+ Termonad.Prelude: takeWhile :: IsSequence seq => Element seq -> Bool -> seq -> seq
+ Termonad.Prelude: tan :: Floating a => a -> a
+ Termonad.Prelude: tanh :: Floating a => a -> a
+ Termonad.Prelude: terror :: HasCallStack => Text -> a
+ Termonad.Prelude: textToBuilder :: ToBuilder Text builder => Text -> builder
+ Termonad.Prelude: throwIO :: (MonadIO m, Exception e) => e -> m a
+ Termonad.Prelude: throwString :: (MonadIO m, HasCallStack) => String -> m a
+ Termonad.Prelude: throwTo :: (Exception e, MonadIO m) => ThreadId -> e -> m ()
+ Termonad.Prelude: timeout :: MonadUnliftIO m => Int -> m a -> m Maybe a
+ Termonad.Prelude: tlshow :: Show a => a -> LText
+ Termonad.Prelude: toAsyncException :: Exception e => e -> SomeException
+ Termonad.Prelude: toBuilder :: ToBuilder value builder => value -> builder
+ Termonad.Prelude: toByteVector :: ByteString -> SVector Word8
+ Termonad.Prelude: toCaseFold :: Textual t => t -> t
+ Termonad.Prelude: toChunks :: LazySequence lazy strict => lazy -> [strict]
+ Termonad.Prelude: toEnum :: Enum a => Int -> a
+ Termonad.Prelude: toException :: Exception e => e -> SomeException
+ Termonad.Prelude: toGregorian :: Day -> (Integer, Int, Int)
+ Termonad.Prelude: toIO :: MonadUnliftIO m => m a -> m IO a
+ Termonad.Prelude: toInteger :: Integral a => a -> Integer
+ Termonad.Prelude: toList :: MonoFoldable mono => mono -> [Element mono]
+ Termonad.Prelude: toLower :: Textual t => t -> t
+ Termonad.Prelude: toMinList :: () => NonEmpty a -> NonNull [a]
+ Termonad.Prelude: toRational :: Real a => a -> Rational
+ Termonad.Prelude: toStrict :: LazySequence lazy strict => lazy -> strict
+ Termonad.Prelude: toSyncException :: Exception e => e -> SomeException
+ Termonad.Prelude: toUpper :: Textual t => t -> t
+ Termonad.Prelude: trace :: () => String -> a -> a
+ Termonad.Prelude: traceId :: String -> String
+ Termonad.Prelude: traceM :: Monad m => String -> m ()
+ Termonad.Prelude: traceShow :: Show a => a -> b -> b
+ Termonad.Prelude: traceShowId :: Show a => a -> a
+ Termonad.Prelude: traceShowM :: (Show a, Monad m) => a -> m ()
+ Termonad.Prelude: traverse :: (Traversable t, Applicative f) => a -> f b -> t a -> f t b
+ Termonad.Prelude: traverse_ :: (MonoFoldable mono, Applicative f) => Element mono -> f b -> mono -> f ()
+ Termonad.Prelude: truncate :: (RealFrac a, Integral b) => a -> b
+ Termonad.Prelude: try :: (MonadUnliftIO m, Exception e) => m a -> m Either e a
+ Termonad.Prelude: tryAny :: MonadUnliftIO m => m a -> m Either SomeException a
+ Termonad.Prelude: tryAnyDeep :: (MonadUnliftIO m, NFData a) => m a -> m Either SomeException a
+ Termonad.Prelude: tryDeep :: (MonadUnliftIO m, Exception e, NFData a) => m a -> m Either e a
+ Termonad.Prelude: tryIO :: MonadUnliftIO m => m a -> m Either IOException a
+ Termonad.Prelude: tryIOError :: () => IO a -> IO Either IOError a
+ Termonad.Prelude: tryJust :: (MonadUnliftIO m, Exception e) => e -> Maybe b -> m a -> m Either b a
+ Termonad.Prelude: tryPeekTBChan :: () => TBChan a -> STM Maybe a
+ Termonad.Prelude: tryPeekTBMChan :: () => TBMChan a -> STM Maybe Maybe a
+ Termonad.Prelude: tryPeekTBMQueue :: () => TBMQueue a -> STM Maybe Maybe a
+ Termonad.Prelude: tryPeekTBQueue :: () => TBQueue a -> STM Maybe a
+ Termonad.Prelude: tryPeekTChan :: () => TChan a -> STM Maybe a
+ Termonad.Prelude: tryPeekTMChan :: () => TMChan a -> STM Maybe Maybe a
+ Termonad.Prelude: tryPeekTMQueue :: () => TMQueue a -> STM Maybe Maybe a
+ Termonad.Prelude: tryPeekTQueue :: () => TQueue a -> STM Maybe a
+ Termonad.Prelude: tryPutMVar :: MonadIO m => MVar a -> a -> m Bool
+ Termonad.Prelude: tryPutTMVar :: () => TMVar a -> a -> STM Bool
+ Termonad.Prelude: tryReadMVar :: MonadIO m => MVar a -> m Maybe a
+ Termonad.Prelude: tryReadTBChan :: () => TBChan a -> STM Maybe a
+ Termonad.Prelude: tryReadTBMChan :: () => TBMChan a -> STM Maybe Maybe a
+ Termonad.Prelude: tryReadTBMQueue :: () => TBMQueue a -> STM Maybe Maybe a
+ Termonad.Prelude: tryReadTBQueue :: () => TBQueue a -> STM Maybe a
+ Termonad.Prelude: tryReadTChan :: () => TChan a -> STM Maybe a
+ Termonad.Prelude: tryReadTMChan :: () => TMChan a -> STM Maybe Maybe a
+ Termonad.Prelude: tryReadTMQueue :: () => TMQueue a -> STM Maybe Maybe a
+ Termonad.Prelude: tryReadTMVar :: () => TMVar a -> STM Maybe a
+ Termonad.Prelude: tryReadTQueue :: () => TQueue a -> STM Maybe a
+ Termonad.Prelude: tryTakeMVar :: MonadIO m => MVar a -> m Maybe a
+ Termonad.Prelude: tryTakeTMVar :: () => TMVar a -> STM Maybe a
+ Termonad.Prelude: tryWriteTBChan :: () => TBChan a -> a -> STM Bool
+ Termonad.Prelude: tryWriteTBMChan :: () => TBMChan a -> a -> STM Maybe Bool
+ Termonad.Prelude: tryWriteTBMQueue :: () => TBMQueue a -> a -> STM Maybe Bool
+ Termonad.Prelude: tshow :: Show a => a -> Text
+ Termonad.Prelude: type BDeque = Deque MVector
+ Termonad.Prelude: type BlazeBuilder = Builder
+ Termonad.Prelude: type ByteStringBuilder = Builder
+ Termonad.Prelude: type FilePath = String
+ Termonad.Prelude: type IOBRef = BRef PrimState IO
+ Termonad.Prelude: type IOError = IOException
+ Termonad.Prelude: type IOPRef = PRef PrimState IO
+ Termonad.Prelude: type IOSRef = SRef PrimState IO
+ Termonad.Prelude: type IOURef = URef PrimState IO
+ Termonad.Prelude: type LByteString = ByteString
+ Termonad.Prelude: type LText = Text
+ Termonad.Prelude: type MutableDeque c = (MutableQueue c, MutablePushFront c, MutablePopBack c)
+ Termonad.Prelude: type MutableQueue c = (MutablePopFront c, MutablePushBack c)
+ Termonad.Prelude: type MutableStack c = (MutablePopFront c, MutablePushFront c)
+ Termonad.Prelude: type Rational = Ratio Integer
+ Termonad.Prelude: type Reader r = ReaderT r Identity
+ Termonad.Prelude: type SDeque = Deque MVector
+ Termonad.Prelude: type SVector = Vector
+ Termonad.Prelude: type String = [Char]
+ Termonad.Prelude: type TextBuilder = Builder
+ Termonad.Prelude: type UDeque = Deque MVector
+ Termonad.Prelude: type UVector = Vector
+ Termonad.Prelude: type family Index seq :: *;
+ Termonad.Prelude: unGetTBChan :: () => TBChan a -> a -> STM ()
+ Termonad.Prelude: unGetTBMChan :: () => TBMChan a -> a -> STM ()
+ Termonad.Prelude: unGetTBMQueue :: () => TBMQueue a -> a -> STM ()
+ Termonad.Prelude: unGetTBQueue :: () => TBQueue a -> a -> STM ()
+ Termonad.Prelude: unGetTChan :: () => TChan a -> a -> STM ()
+ Termonad.Prelude: unGetTMChan :: () => TMChan a -> a -> STM ()
+ Termonad.Prelude: unGetTMQueue :: () => TMQueue a -> a -> STM ()
+ Termonad.Prelude: unGetTQueue :: () => TQueue a -> a -> STM ()
+ Termonad.Prelude: uncons :: IsSequence seq => seq -> Maybe (Element seq, seq)
+ Termonad.Prelude: uncurry :: () => a -> b -> c -> (a, b) -> c
+ Termonad.Prelude: undefined :: HasCallStack => a
+ Termonad.Prelude: uninterruptibleCancel :: MonadIO m => Async a -> m ()
+ Termonad.Prelude: uninterruptibleMask :: MonadUnliftIO m => forall a. () => m a -> m a -> m b -> m b
+ Termonad.Prelude: uninterruptibleMask_ :: MonadUnliftIO m => m a -> m a
+ Termonad.Prelude: union :: SetContainer set => set -> set -> set
+ Termonad.Prelude: unionWith :: IsMap map => MapValue map -> MapValue map -> MapValue map -> map -> map -> map
+ Termonad.Prelude: unionWithKey :: IsMap map => ContainerKey map -> MapValue map -> MapValue map -> MapValue map -> map -> map -> map
+ Termonad.Prelude: unions :: (SetContainer set, MonoFoldable mono, Element mono ~ set) => mono -> set
+ Termonad.Prelude: unionsWith :: IsMap map => MapValue map -> MapValue map -> MapValue map -> [map] -> map
+ Termonad.Prelude: unless :: Applicative f => Bool -> f () -> f ()
+ Termonad.Prelude: unlessM :: Monad m => m Bool -> m () -> m ()
+ Termonad.Prelude: unlines :: (Textual t, Element seq ~ t, MonoFoldable seq) => seq -> t
+ Termonad.Prelude: unpack :: MonoFoldable mono => mono -> [Element mono]
+ Termonad.Prelude: unsafeDrop :: IsSequence seq => Index seq -> seq -> seq
+ Termonad.Prelude: unsafeHead :: MonoFoldable mono => mono -> Element mono
+ Termonad.Prelude: unsafeIndex :: IsSequence seq => seq -> Index seq -> Element seq
+ Termonad.Prelude: unsafeInit :: IsSequence seq => seq -> seq
+ Termonad.Prelude: unsafeLast :: MonoFoldable mono => mono -> Element mono
+ Termonad.Prelude: unsafeSplitAt :: IsSequence seq => Index seq -> seq -> (seq, seq)
+ Termonad.Prelude: unsafeTail :: IsSequence seq => seq -> seq
+ Termonad.Prelude: unsafeTake :: IsSequence seq => Index seq -> seq -> seq
+ Termonad.Prelude: unsnoc :: IsSequence seq => seq -> Maybe (seq, Element seq)
+ Termonad.Prelude: until :: () => a -> Bool -> a -> a -> a -> a
+ Termonad.Prelude: unwords :: (Textual t, Element seq ~ t, MonoFoldable seq) => seq -> t
+ Termonad.Prelude: unzip :: Zip f => f (a, b) -> (f a, f b)
+ Termonad.Prelude: unzip3 :: Zip3 f => f (a, b, c) -> (f a, f b, f c)
+ Termonad.Prelude: unzip4 :: Zip4 f => f (a, b, c, d) -> (f a, f b, f c, f d)
+ Termonad.Prelude: unzip5 :: Zip5 f => f (a, b, c, d, e) -> (f a, f b, f c, f d, f e)
+ Termonad.Prelude: unzip6 :: Zip6 f => f (a, b, c, d, e, g) -> (f a, f b, f c, f d, f e, f g)
+ Termonad.Prelude: unzip7 :: Zip7 f => f (a, b, c, d, e, g, h) -> (f a, f b, f c, f d, f e, f g, f h)
+ Termonad.Prelude: updateLookupWithKey :: IsMap map => ContainerKey map -> MapValue map -> Maybe MapValue map -> ContainerKey map -> map -> (Maybe MapValue map, map)
+ Termonad.Prelude: updateMap :: IsMap map => MapValue map -> Maybe MapValue map -> ContainerKey map -> map -> map
+ Termonad.Prelude: updateWithKey :: IsMap map => ContainerKey map -> MapValue map -> Maybe MapValue map -> ContainerKey map -> map -> map
+ Termonad.Prelude: userError :: String -> IOError
+ Termonad.Prelude: userErrorType :: IOErrorType
+ Termonad.Prelude: vectorSort :: (Vector v e, Ord e) => v e -> v e
+ Termonad.Prelude: vectorSortBy :: Vector v e => e -> e -> Ordering -> v e -> v e
+ Termonad.Prelude: void :: Functor f => f a -> f ()
+ Termonad.Prelude: wait :: MonadIO m => Async a -> m a
+ Termonad.Prelude: waitAny :: MonadIO m => [Async a] -> m (Async a, a)
+ Termonad.Prelude: waitAnyCancel :: MonadIO m => [Async a] -> m (Async a, a)
+ Termonad.Prelude: waitAnyCatch :: MonadIO m => [Async a] -> m (Async a, Either SomeException a)
+ Termonad.Prelude: waitAnyCatchCancel :: MonadIO m => [Async a] -> m (Async a, Either SomeException a)
+ Termonad.Prelude: waitAnyCatchSTM :: () => [Async a] -> STM (Async a, Either SomeException a)
+ Termonad.Prelude: waitAnySTM :: () => [Async a] -> STM (Async a, a)
+ Termonad.Prelude: waitAsync :: MonadIO m => Async a -> m a
+ Termonad.Prelude: waitBoth :: MonadIO m => Async a -> Async b -> m (a, b)
+ Termonad.Prelude: waitBothSTM :: () => Async a -> Async b -> STM (a, b)
+ Termonad.Prelude: waitCatch :: MonadIO m => Async a -> m Either SomeException a
+ Termonad.Prelude: waitCatchAsync :: MonadIO m => Async a -> m Either SomeException a
+ Termonad.Prelude: waitCatchSTM :: () => Async a -> STM Either SomeException a
+ Termonad.Prelude: waitEither :: MonadIO m => Async a -> Async b -> m Either a b
+ Termonad.Prelude: waitEitherCancel :: MonadIO m => Async a -> Async b -> m Either a b
+ Termonad.Prelude: waitEitherCatch :: MonadIO m => Async a -> Async b -> m Either Either SomeException a Either SomeException b
+ Termonad.Prelude: waitEitherCatchCancel :: MonadIO m => Async a -> Async b -> m Either Either SomeException a Either SomeException b
+ Termonad.Prelude: waitEitherCatchSTM :: () => Async a -> Async b -> STM Either Either SomeException a Either SomeException b
+ Termonad.Prelude: waitEitherSTM :: () => Async a -> Async b -> STM Either a b
+ Termonad.Prelude: waitEitherSTM_ :: () => Async a -> Async b -> STM ()
+ Termonad.Prelude: waitEither_ :: MonadIO m => Async a -> Async b -> m ()
+ Termonad.Prelude: waitSTM :: () => Async a -> STM a
+ Termonad.Prelude: when :: Applicative f => Bool -> f () -> f ()
+ Termonad.Prelude: whenJust :: Monoid m => Maybe a -> (a -> m) -> m
+ Termonad.Prelude: whenM :: Monad m => m Bool -> m () -> m ()
+ Termonad.Prelude: withAsync :: MonadUnliftIO m => m a -> Async a -> m b -> m b
+ Termonad.Prelude: withAsyncBound :: MonadUnliftIO m => m a -> Async a -> m b -> m b
+ Termonad.Prelude: withAsyncOn :: MonadUnliftIO m => Int -> m a -> Async a -> m b -> m b
+ Termonad.Prelude: withAsyncOnWithUnmask :: MonadUnliftIO m => Int -> forall c. () => m c -> m c -> m a -> Async a -> m b -> m b
+ Termonad.Prelude: withAsyncWithUnmask :: MonadUnliftIO m => forall c. () => m c -> m c -> m a -> Async a -> m b -> m b
+ Termonad.Prelude: withBinaryFile :: MonadUnliftIO m => FilePath -> IOMode -> Handle -> m a -> m a
+ Termonad.Prelude: withException :: (MonadUnliftIO m, Exception e) => m a -> e -> m b -> m a
+ Termonad.Prelude: withFile :: MonadUnliftIO m => FilePath -> IOMode -> Handle -> m a -> m a
+ Termonad.Prelude: withMVar :: MonadUnliftIO m => MVar a -> a -> m b -> m b
+ Termonad.Prelude: withMVarMasked :: MonadUnliftIO m => MVar a -> a -> m b -> m b
+ Termonad.Prelude: withRunInIO :: MonadUnliftIO m => forall a. () => m a -> IO a -> IO b -> m b
+ Termonad.Prelude: withSystemTempDirectory :: MonadUnliftIO m => String -> FilePath -> m a -> m a
+ Termonad.Prelude: withSystemTempFile :: MonadUnliftIO m => String -> FilePath -> Handle -> m a -> m a
+ Termonad.Prelude: withTempDirectory :: MonadUnliftIO m => FilePath -> String -> FilePath -> m a -> m a
+ Termonad.Prelude: withTempFile :: MonadUnliftIO m => FilePath -> String -> FilePath -> Handle -> m a -> m a
+ Termonad.Prelude: withUnliftIO :: MonadUnliftIO m => UnliftIO m -> IO a -> m a
+ Termonad.Prelude: words :: Textual t => t -> [t]
+ Termonad.Prelude: wrappedWithRunInIO :: MonadUnliftIO n => n b -> m b -> forall a. () => m a -> n a -> forall a. () => m a -> IO a -> IO b -> m b
+ Termonad.Prelude: writeChan :: MonadIO m => Chan a -> a -> m ()
+ Termonad.Prelude: writeFile :: MonadIO m => FilePath -> ByteString -> m ()
+ Termonad.Prelude: writeFileUtf8 :: MonadIO m => FilePath -> Text -> m ()
+ Termonad.Prelude: writeIORef :: MonadIO m => IORef a -> a -> m ()
+ Termonad.Prelude: writeList2Chan :: MonadIO m => Chan a -> [a] -> m ()
+ Termonad.Prelude: writeMutVar :: PrimMonad m => MutVar PrimState m a -> a -> m ()
+ Termonad.Prelude: writeRef :: (MutableRef c, PrimMonad m, PrimState m ~ MCState c) => c -> RefElement c -> m ()
+ Termonad.Prelude: writeTBChan :: () => TBChan a -> a -> STM ()
+ Termonad.Prelude: writeTBMChan :: () => TBMChan a -> a -> STM ()
+ Termonad.Prelude: writeTBMQueue :: () => TBMQueue a -> a -> STM ()
+ Termonad.Prelude: writeTBQueue :: () => TBQueue a -> a -> STM ()
+ Termonad.Prelude: writeTChan :: () => TChan a -> a -> STM ()
+ Termonad.Prelude: writeTMChan :: () => TMChan a -> a -> STM ()
+ Termonad.Prelude: writeTMQueue :: () => TMQueue a -> a -> STM ()
+ Termonad.Prelude: writeTQueue :: () => TQueue a -> a -> STM ()
+ Termonad.Prelude: writeTVar :: () => TVar a -> a -> STM ()
+ Termonad.Prelude: yieldThread :: MonadIO m => m ()
+ Termonad.Prelude: zip :: Zip f => f a -> f b -> f (a, b)
+ Termonad.Prelude: zip3 :: Zip3 f => f a -> f b -> f c -> f (a, b, c)
+ Termonad.Prelude: zip4 :: Zip4 f => f a -> f b -> f c -> f d -> f (a, b, c, d)
+ Termonad.Prelude: zip5 :: Zip5 f => f a -> f b -> f c -> f d -> f e -> f (a, b, c, d, e)
+ Termonad.Prelude: zip6 :: Zip6 f => f a -> f b -> f c -> f d -> f e -> f g -> f (a, b, c, d, e, g)
+ Termonad.Prelude: zip7 :: Zip7 f => f a -> f b -> f c -> f d -> f e -> f g -> f h -> f (a, b, c, d, e, g, h)
+ Termonad.Prelude: zipWith :: Zip f => a -> b -> c -> f a -> f b -> f c
+ Termonad.Prelude: zipWith3 :: Zip3 f => a -> b -> c -> d -> f a -> f b -> f c -> f d
+ Termonad.Prelude: zipWith4 :: Zip4 f => a -> b -> c -> d -> e -> f a -> f b -> f c -> f d -> f e
+ Termonad.Prelude: zipWith5 :: Zip5 f => a -> b -> c -> d -> e -> g -> f a -> f b -> f c -> f d -> f e -> f g
+ Termonad.Prelude: zipWith6 :: Zip6 f => a -> b -> c -> d -> e -> g -> h -> f a -> f b -> f c -> f d -> f e -> f g -> f h
+ Termonad.Prelude: zipWith7 :: Zip7 f => a -> b -> c -> d -> e -> g -> h -> i -> f a -> f b -> f c -> f d -> f e -> f g -> f h -> f i
+ Termonad.Prelude: }
+ Termonad.Term: setShowTabs :: TMConfig -> Notebook -> IO ()
+ Termonad.Term: termClose :: TMNotebookTab -> TMState -> IO ()
+ Termonad.Term: toRGBA :: Colour Double -> IO RGBA
+ Termonad.Types: ConfigHooks :: TMState -> Terminal -> IO () -> ConfigHooks
+ Termonad.Types: ConfigOptions :: !FontConfig -> !ShowScrollbar -> !Integer -> !Bool -> !Text -> !Bool -> !ShowTabBar -> !CursorBlinkMode -> ConfigOptions
+ Termonad.Types: FocusListFocusExistsButNoNotebookTabWidget :: FocusNotSameErr
+ Termonad.Types: FocusNotSame :: FocusNotSameErr -> Int -> TMStateInvariantErr
+ Termonad.Types: FontConfig :: !Text -> !FontSize -> FontConfig
+ Termonad.Types: FontSizePoints :: Int -> FontSize
+ Termonad.Types: FontSizeUnits :: Double -> FontSize
+ Termonad.Types: NotebookTabWidgetDiffersFromFocusListFocus :: FocusNotSameErr
+ Termonad.Types: NotebookTabWidgetExistsButNoFocusListFocus :: FocusNotSameErr
+ Termonad.Types: Set :: !a -> Option a
+ Termonad.Types: ShowScrollbarAlways :: ShowScrollbar
+ Termonad.Types: ShowScrollbarIfNeeded :: ShowScrollbar
+ Termonad.Types: ShowScrollbarNever :: ShowScrollbar
+ Termonad.Types: ShowTabBarAlways :: ShowTabBar
+ Termonad.Types: ShowTabBarIfNeeded :: ShowTabBar
+ Termonad.Types: ShowTabBarNever :: ShowTabBar
+ Termonad.Types: TMConfig :: !ConfigOptions -> !ConfigHooks -> TMConfig
+ Termonad.Types: TabAtIndexDifferent :: Int -> TabsDoNotMatch
+ Termonad.Types: TabLengthsDifferent :: Int -> Int -> TabsDoNotMatch
+ Termonad.Types: TabsDoNotMatch :: TabsDoNotMatch -> TMStateInvariantErr
+ Termonad.Types: Unset :: Option a
+ Termonad.Types: [confirmExit] :: ConfigOptions -> !Bool
+ Termonad.Types: [createTermHook] :: ConfigHooks -> TMState -> Terminal -> IO ()
+ Termonad.Types: [cursorBlinkMode] :: ConfigOptions -> !CursorBlinkMode
+ Termonad.Types: [fontConfig] :: ConfigOptions -> !FontConfig
+ Termonad.Types: [fontFamily] :: FontConfig -> !Text
+ Termonad.Types: [fontSize] :: FontConfig -> !FontSize
+ Termonad.Types: [hooks] :: TMConfig -> !ConfigHooks
+ Termonad.Types: [options] :: TMConfig -> !ConfigOptions
+ Termonad.Types: [scrollbackLen] :: ConfigOptions -> !Integer
+ Termonad.Types: [showMenu] :: ConfigOptions -> !Bool
+ Termonad.Types: [showScrollbar] :: ConfigOptions -> !ShowScrollbar
+ Termonad.Types: [showTabBar] :: ConfigOptions -> !ShowTabBar
+ Termonad.Types: [wordCharExceptions] :: ConfigOptions -> !Text
+ Termonad.Types: assertInvariantTMState :: TMState -> IO ()
+ Termonad.Types: data ConfigHooks
+ Termonad.Types: data ConfigOptions
+ Termonad.Types: data FocusNotSameErr
+ Termonad.Types: data FontConfig
+ Termonad.Types: data FontSize
+ Termonad.Types: data Option a
+ Termonad.Types: data ShowScrollbar
+ Termonad.Types: data ShowTabBar
+ Termonad.Types: data TMConfig
+ Termonad.Types: data TMStateInvariantErr
+ Termonad.Types: data TabsDoNotMatch
+ Termonad.Types: defaultConfigHooks :: ConfigHooks
+ Termonad.Types: defaultConfigOptions :: ConfigOptions
+ Termonad.Types: defaultCreateTermHook :: TMState -> Terminal -> IO ()
+ Termonad.Types: defaultFontConfig :: FontConfig
+ Termonad.Types: defaultFontSize :: FontSize
+ Termonad.Types: defaultTMConfig :: TMConfig
+ Termonad.Types: instance Data.Foldable.Foldable Termonad.Types.Option
+ Termonad.Types: instance GHC.Base.Functor Termonad.Types.Option
+ Termonad.Types: instance GHC.Classes.Eq Termonad.Types.ConfigOptions
+ Termonad.Types: instance GHC.Classes.Eq Termonad.Types.FontConfig
+ Termonad.Types: instance GHC.Classes.Eq Termonad.Types.FontSize
+ Termonad.Types: instance GHC.Classes.Eq Termonad.Types.ShowScrollbar
+ Termonad.Types: instance GHC.Classes.Eq Termonad.Types.ShowTabBar
+ Termonad.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Termonad.Types.Option a)
+ Termonad.Types: instance GHC.Classes.Ord a => GHC.Classes.Ord (Termonad.Types.Option a)
+ Termonad.Types: instance GHC.Read.Read a => GHC.Read.Read (Termonad.Types.Option a)
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.ConfigHooks
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.ConfigOptions
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.FocusNotSameErr
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.FontConfig
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.FontSize
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.ShowScrollbar
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.ShowTabBar
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.TMConfig
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.TMStateInvariantErr
+ Termonad.Types: instance GHC.Show.Show Termonad.Types.TabsDoNotMatch
+ Termonad.Types: instance GHC.Show.Show a => GHC.Show.Show (Termonad.Types.Option a)
+ Termonad.Types: invariantTMState' :: TMState' -> IO [TMStateInvariantErr]
+ Termonad.Types: notebookToList :: Notebook -> IO [Widget]
+ Termonad.Types: pPrintTMState :: TMState -> IO ()
+ Termonad.Types: whenSet :: Monoid m => Option a -> (a -> m) -> m
- Termonad.App: compareScrolledWinAndTab :: ScrolledWindow -> a -> TMNotebookTab -> Bool
+ Termonad.App: compareScrolledWinAndTab :: ScrolledWindow -> TMNotebookTab -> Bool
- Termonad.Config: FontConfig :: !Text -> !Int -> FontConfig
+ Termonad.Config: FontConfig :: !Text -> !FontSize -> FontConfig
- Termonad.Config: TMConfig :: !FontConfig -> !ShowScrollbar -> !(Colour Double) -> !Integer -> TMConfig
+ Termonad.Config: TMConfig :: !ConfigOptions -> !ConfigHooks -> TMConfig
- Termonad.Config: [fontConfig] :: TMConfig -> !FontConfig
+ Termonad.Config: [fontConfig] :: ConfigOptions -> !FontConfig
- Termonad.Config: [fontSize] :: FontConfig -> !Int
+ Termonad.Config: [fontSize] :: FontConfig -> !FontSize
- Termonad.Config: [scrollbackLen] :: TMConfig -> !Integer
+ Termonad.Config: [scrollbackLen] :: ConfigOptions -> !Integer
- Termonad.Config: [showScrollbar] :: TMConfig -> !ShowScrollbar
+ Termonad.Config: [showScrollbar] :: ConfigOptions -> !ShowScrollbar
- Termonad.Types: TMState :: !Application -> !ApplicationWindow -> !TMNotebook -> !FontDescription -> !TMConfig -> !UserRequestedExit -> TMState'
+ Termonad.Types: TMState :: !Application -> !ApplicationWindow -> !TMNotebook -> !FontDescription -> !TMConfig -> TMState'
Files
- .nix-helpers/nixpkgs.nix +93/−8
- .nix-helpers/running-termonad.nix +0/−26
- .nix-helpers/stack-nix-shell.nix +15/−13
- .nix-helpers/termonad-with-packages.nix +122/−0
- .nix-helpers/termonad.nix +0/−34
- CHANGELOG.md +8/−0
- README.md +150/−58
- default.nix +19/−28
- example-config/ExampleColourExtension.hs +72/−0
- img/termonad-lambda.png binary
- shell.nix +43/−9
- src/Termonad.hs +13/−1
- src/Termonad/App.hs +169/−82
- src/Termonad/Config.hs +59/−55
- src/Termonad/Config/Colour.hs +518/−0
- src/Termonad/Config/Vec.hs +564/−0
- src/Termonad/FocusList.hs +0/−830
- src/Termonad/Gtk.hs +25/−3
- src/Termonad/Keys.hs +2/−0
- src/Termonad/Lenses.hs +76/−0
- src/Termonad/Prelude.hs +5/−2
- src/Termonad/Term.hs +80/−37
- src/Termonad/Types.hs +372/−78
- termonad.cabal +72/−6
- test/Test.hs +1/−129
- test/readme/README.lhs +405/−0
.nix-helpers/nixpkgs.nix view
@@ -1,11 +1,96 @@-# This file pins the version of nixpkgs to a known good version.-# It is imported from various other files.+# This file pins the version of nixpkgs to a known good version. The nixpkgs is+# imported with an overlay overriding haskellPackages to generate haddocks for+# GI dependencies, and to use the GHC, VTE, GTK and open-haddock versions we+# want. It is imported from various other files. +{ compiler ? null, nixpkgs ? null }:+ let- nixpkgsTarball = builtins.fetchTarball {- # recent version of nixpkgs as of 2018-07-29- url = "https://github.com/NixOS/nixpkgs/archive/a2c6dbe370160ffea5537f64dda04489184c5ce1.tar.gz";- sha256 = "1x993g9343yv5wyp29i6vskdcc3rl42xipv79nwmmrj8ay2yhh3b";+ # recent version of nixpkgs as of 2018-11-09+ nixpkgsSrc =+ if isNull nixpkgs+ then+ builtins.fetchTarball {+ url = "https://github.com/NixOS/nixpkgs/archive/237285295764fb063ec1ca509c36b17c4990eeb4.tar.gz";+ sha256 = "1cl40yz7ry6x2nbzpc5pkf0q5p0fxvi0c2n7la0pz5g1n80n4xlq";+ }+ else+ nixpkgs;++ compilerVersion = if isNull compiler then "ghc844" else compiler;++ # The termonad derivation is generated automatically with `cabal2nix`.+ termonadOverride =+ stdenvLib: gnome3: callCabal2nix: overrideCabal:+ let+ src =+ builtins.filterSource+ (path: type: with stdenvLib;+ ! elem (baseNameOf path) [ ".git" "result" ".stack-work" ] &&+ ! any (flip hasPrefix (baseNameOf path)) [ "dist" ".ghc" ]+ )+ ./..;+ termonad = callCabal2nix "termonad" src {+ inherit (gnome3) gtk3;+ };+ in+ overrideCabal termonad (oldAttrs: {+ # For some reason the doctests fail when running with nix.+ # https://github.com/cdepillabout/termonad/issues/15+ doCheck = false;+ });++ myfocuslist = callCabal2nix:+ let+ src = builtins.fetchTarball {+ url = "https://github.com/cdepillabout/focuslist/archive/80bd865e82ab4499ccebcd89989d2dbb221bb381.tar.gz";+ sha256 = "1b7da9ngk34jc2w4hhqq6qv20pkch5vvi34kr81xpmr3mmiwqmai";+ };+ in callCabal2nix "focuslist" src {};++ gobjIntroOverride = oldAttrs: {+ patches = oldAttrs.patches ++ [ ./macos-gobject-introspection-rpath.patch ]; };-in-import nixpkgsTarball { }++ haskellPackagesOL = self: super: with super.haskell.lib; {+ haskellPackages = super.haskell.packages.${compilerVersion}.override {+ overrides = hself: hsuper: {+ # Only override the version of foculist if it doesn't already exist in+ # the haskell package set.+ focuslist = hsuper.focuslist or (myfocuslist hself.callCabal2nix);++ # Set the haskell-gi libraries to generate documentation.+ gi-gdk = doHaddock hsuper.gi-gdk;+ gi-gio = doHaddock hsuper.gi-gio;+ gi-glib = doHaddock hsuper.gi-glib;+ gi-gtk = doHaddock hsuper.gi-gtk;+ gi-pango = doHaddock hsuper.gi-pango;+ gi-vte = doHaddock hsuper.gi-vte;++ termonad = termonadOverride self.stdenv.lib self.gnome3 hself.callCabal2nix self.haskell.lib.overrideCabal;++ # This is a tool to use to easily open haddocks in the browser.+ open-haddock = hsuper.open-haddock.overrideAttrs (oa: {+ src = super.fetchFromGitHub {+ owner = "jml";+ repo = "open-haddock";+ rev = "472d10d61d7b9262626171af0484a65365863fa6";+ sha256 = "072d680j1k3n0vkzsbghhnah2p799yxrm7mhvr0nkdvr7iy04gcz";+ };+ });+ };+ };++ # Darwin needs a patch to gobject-introspection:+ # https://github.com/NixOS/nixpkgs/pull/46310+ gobjectIntrospection = super.gobjectIntrospection.overrideAttrs (oldAttrs: {+ patches =+ oldAttrs.patches +++ (if self.stdenv.isDarwin+ then [ ./macos-gobject-introspection-rpath.patch ]+ else [ ]);+ });+ };++in import nixpkgsSrc { overlays = [ haskellPackagesOL ]; }+
− .nix-helpers/running-termonad.nix
@@ -1,26 +0,0 @@-# Running `nix-shell .nix-helpers/running-termonad.nix` will put us in an environment-# with termonad available, as well as GHC and a few other packages (lens and colour).-#-# If you run `termonad` while in this environment, `termonad` should be able to see-# GHC and all the Haskell libraries listed below. This will let `termonad` be able to-# recompile the `~/.config/termonad/termonad.hs` file.-#-# This file is really only used when you want to run termonad in an environment where it-# has access to specific libraries.--{ compiler ? "ghc843" }:--let- nixpkgs = import ./nixpkgs.nix;-- termonad = nixpkgs.callPackage ../. { inherit compiler; };-- ghcStuff = nixpkgs.pkgs.haskell.packages.${compiler}.ghcWithPackages (pkgs: [- pkgs.colour- pkgs.lens- termonad- ]);--in--nixpkgs.runCommand "dummy" { buildInputs = [ ghcStuff termonad ]; } ""
.nix-helpers/stack-nix-shell.nix view
@@ -1,21 +1,22 @@ # This is the shell file specified in the stack.yaml file.-# This forces stack to use ghc-8.0.2 and stack-lts-9.yaml to compile termonad.+# This runs stack commands in an environment created with nix. let+ # recent version of nixpkgs as of 2018-10-17 nixpkgsTarball = builtins.fetchTarball {- # 17.09 (this works)- #url = "https://github.com/NixOS/nixpkgs/archive/39cd40f7bea40116ecb756d46a687bfd0d2e550e.tar.gz";- #sha256 = "0kpx4h9p1lhjbn1gsil111swa62hmjs9g93xmsavfiki910s73sh";+ url = "https://github.com/NixOS/nixpkgs/archive/6a23e11e658b7a7a77f1b61d30d64153b46bc852.tar.gz";+ sha256 = "03n4bacfk1bbx3v0cx8xcgcmz44l0knswzh7hwih9nx0hj3x41yc";+ }; - # 18.03- url = "https://github.com/NixOS/nixpkgs/archive/120b013e0c082d58a5712cde0a7371ae8b25a601.tar.gz";- sha256 = "0hk4y2vkgm1qadpsm4b0q1vxq889jhxzjx3ragybrlwwg54mzp4f";+ # Fixes for individual packages. Currently none needed.+ pkgFixes = self: pkgs: {+ }; - # recent version of nixpkgs as of 2018-07-25 (this only seems to sometimes work...?))- #url = "https://github.com/NixOS/nixpkgs/archive/4ccaa7de8eb34a0bb140f109a0e88095480118eb.tar.gz";- #sha256 = "0szbxfrzmlmxrgkqz5wnfgmsjp82vaddgz7mhdz7jj0jhd0hza4i";+ nixpkgs = import nixpkgsTarball {+ overlays = [+ pkgFixes+ ]; };- nixpkgs = import nixpkgsTarball { }; in with nixpkgs;@@ -24,13 +25,14 @@ name = "termonad"; buildInputs = [ cairo+ git gnome3.vte gobjectIntrospection gtk3 zlib ];- ghc = haskell.compiler.ghc802;+ ghc = haskell.compiler.ghc843; extraArgs = [- "--stack-yaml stack-lts-9.yaml"+ "--stack-yaml stack-lts-12.yaml" ]; }
+ .nix-helpers/termonad-with-packages.nix view
@@ -0,0 +1,122 @@+# This file produces a wrapper around Termonad that will know where to find a+# GHC with the libraries needed to recompile its config file.+#+# This is not NixOS only; it should work with nix on any system.+#+# There are 4 different ways this file can be used.+#+# 1. build directly with `nix-build`+#+# This method allows you to build termonad from the command line with+# `nix-build`. This is the easiest method.+#+# You can call `nix-build` like the following:+#+# $ nix-build .nix-helpers/termonad-with-packages.nix+#+# (This is the same as just calling `nix-build` on the `../default.nix` file.)+#+# This produces a `result` directory that contains the `termonad` exectuable as+# `result/bin/termonad`.+#+# By default, you will be able to use the Haskell packages `lens` and `colour`+# in your `~/.config/termonad/termonad.hs` configuration file.+#+# If you want to use alternative Haskell packages, you can specify them on the+# command line:+#+# $ nix-build .nix-helpers/termonad-with-packages.nix \+# --arg extraHaskellPackages 'haskellPackages: [ haskellPackages.colour haskellPackages.lens haskellPackages.pipes ]'+#+# This will make sure you can also use the Haskell packages `lens`, `colour`, and `pipes` in your+# `~/.config/termonad/termonad.hs` file. (Actually, if Termonad transitively+# depends on a library, you should be able to use it without having to specify+# it. Although you shouldn't depend on this.)+#+# 2. install with `nix-env`+#+# `nix-env` can be used to install Termonad into your environment:+#+# $ nix-env --file .nix-helpers/termonad-with-packages.nix --install+#+# If you want to specify extra Haskell packages that you can use in your+# `~/.config/termonad/termonad.hs` file, you can call `nix-env` like the+# following:+#+# $ nix-env --file .nix-helpers/termonad-with-packages.nix --install \+# --arg extraHaskellPackages 'haskellPackages: [ haskellPackages.colour haskellPackages.lens haskellPackages.pipes ]'+#+# 3. an overlay for your user+#+# Nix makes it easy to create overlays. First, create the following file at+# `~/.config/nixpkgs/overlays/termonad.nix`:+#+# ```nix+# self: super:+# let extraHaskellPackages = hp: [ hp.colour hp.lens hp.MonadRandom ]; in+# { termonad = import /some/path/to/termonad/.nix-helpers/termonad-with-packages.nix { inherit extraHaskellPackages; };+# }+# ```+#+# Now Termonad can be installed through Nix's standard methods, including `nix-env`:+#+# $ nix-env --file '<nixpkgs>' --install --attr termonad+#+# 4. system-wide in /etc/nixos/configuration.nix+#+# You can set the `nixpkgs.overlays` attribute in your+# `/etc/nixos/configuration.nix` file just like in (3) above.+#+# ```nix+# { config, pkgs, ... }:+# {+# nixpkgs.overlays = [ (import /home/youruser/.config/nixpkgs/overlays/termonad.nix) ];+# }+# ```+#+# You can also add Termonad directly to your system packages:+#+# ```nix+# { config, pkgs, ... }:+# {+# environment.systemPackages = with pkgs; [+# ...+# (import /some/path/to/termonad/.nix-helpers/termonad-with-packages.nix { })+# ...+# ];+# }+# ```++let+ # Default Haskell packages that you can use in your Termonad configuration.+ # This is only used if the user doesn't specify the extraHaskellPackages+ # option.+ defaultPackages = haskellPackages: with haskellPackages; [+ colour+ lens+ ];+in++{ extraHaskellPackages ? defaultPackages+, compiler ? null+, nixpkgs ? null+}:++with (import ./nixpkgs.nix { inherit compiler nixpkgs; });++let+ ghcWithPackages = haskellPackages.ghcWithPackages;+ env = ghcWithPackages (self: [ self.termonad ] ++ extraHaskellPackages self);+in++stdenv.mkDerivation {+ name = "termonad-with-packages-${env.version}";+ nativeBuildInputs = [ makeWrapper ];+ buildCommand = ''+ mkdir -p $out/bin+ makeWrapper ${env}/bin/termonad $out/bin/termonad \+ --set NIX_GHC "${env}/bin/ghc"+ '';+ preferLocalBuild = true;+ allowSubstitutes = false;+}
− .nix-helpers/termonad.nix
@@ -1,34 +0,0 @@-{ mkDerivation, base, Cabal, cabal-doctest, classy-prelude, colour-, constraints, data-default, doctest, dyre, gi-gdk, gi-gio, gi-glib-, gi-gtk, gi-pango, gi-vte, gtk3, haskell-gi-base, hedgehog, lens-, pretty-simple, QuickCheck, stdenv, tasty, tasty-hedgehog-, template-haskell, xml-conduit, xml-html-qq-}:-mkDerivation {- pname = "termonad";- version = "0.2.0.0";- src = builtins.filterSource (path: type:- baseNameOf path != ".git" &&- baseNameOf path != "result" &&- baseNameOf path != ".stack-work" &&- baseNameOf path != "dist") ./..;- isLibrary = true;- isExecutable = true;- doCheck = false;- enableSeparateDataOutput = true;- setupHaskellDepends = [ base Cabal cabal-doctest ];- libraryHaskellDepends = [- base classy-prelude colour constraints data-default dyre gi-gdk- gi-gio gi-glib gi-gtk gi-pango gi-vte haskell-gi-base lens- pretty-simple QuickCheck xml-conduit xml-html-qq- ];- libraryPkgconfigDepends = [ gtk3 ];- executableHaskellDepends = [ base ];- testHaskellDepends = [- base doctest hedgehog lens QuickCheck tasty tasty-hedgehog- template-haskell- ];- homepage = "https://github.com/cdepillabout/termonad";- description = "Terminal emulator configurable in Haskell";- license = stdenv.lib.licenses.bsd3;-}
CHANGELOG.md view
@@ -1,4 +1,12 @@ +## 1.0.0.0++* The API for configuring Termonad is now completely different. Many, many+ changes have gone into this version. You should approach it as a+ completely different application.++ The CHANGELOG will be kept up-to-date for future releases.+ ## 0.2.1.0 * Make sure the window title is set to "Termonad".
README.md view
@@ -6,7 +6,9 @@ [](https://hackage.haskell.org/package/termonad) [](http://stackage.org/lts/package/termonad) [](http://stackage.org/nightly/package/termonad)-+[](./LICENSE)+[](https://gitter.im/termonad/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)+[](https://webchat.freenode.net/) Termonad is a terminal emulator configurable in Haskell. It is extremely customizable and provides hooks to modify the default behavior. It can be@@ -21,15 +23,20 @@ - [Installation](#installation) - [Arch Linux](#arch-linux) - [Ubuntu / Debian](#ubuntu--debian)- - [NixOS](#nixos)+ - [Nix](#nix) - [Mac OS X](#mac-os-x)+ - [Installing with just `stack`](#installing-with-just-stack)+ - [Installing with just `nix`](#installing-with-just-nix)+ - [Installing with `stack` using `nix`](#installing-with-stack-using-nix) - [Windows](#windows) - [How to use Termonad](#how-to-use-termonad)+ - [Default Keybindings](#default-keybindings) - [Configuring Termonad](#configuring-termonad) - [Compiling Local Settings](#compiling-local-settings) - [Running with `stack`](#running-with-stack) - [Running with `nix`](#running-with-nix) - [Goals](#goals)+ - [Where to get help](#where-to-get-help) - [Contributions](#contributions) - [Maintainers](#maintainers) @@ -84,9 +91,11 @@ $ stack install ``` -### NixOS+### Nix -There are two methods to build Termonad on NixOS.+If you have `nix` installed, you should be able to use it to build Termonad.+This means that it will work on NixOS, or with `nix` on another distro. There+are two different ways to use `nix` to build Termonad: The first is using `stack`. The following commands install `stack` for your user, clone this repository, and install the `termonad` binary to `~/.local/bin/`:@@ -109,8 +118,68 @@ ### Mac OS X -(*currently no instructions available. please send a PR adding instructions if you get termonad to build.*)+Building and installing Termonad on Mac OS X should be possible with any of the following three methods: +- Install the required system libraries (like GTK and VTE) by hand, then use+ `stack` to build Termonad.++ This is probably the easiest method. You don't have to understand anything+ about `nix`. However, it is slightly annoying to have to install GTK and+ VTE by hand.++- Use `nix` to install both the required system libraries and Termonad itself.++ If you are a nix user and want an easy way to install Termonad, this+ is the recommended method.++- Use `nix` to install install the required system libraries, and `stack` to+ build Termonad.++ If you are a nix user, but want to use `stack` to actually do development+ on Termonad, using `stack` may be easier than using `cabal`.++The following sections describe each method.++#### Installing with just `stack`++(*currently no instructions available. please send a PR adding instructions if you get termonad to build using this method.*)++#### Installing with just `nix`++`nix` can be used to install Termonad with the following steps, assuming you+have `nix` [installed](https://nixos.org/nix/download.html). These commands+clone this repository and build the `termonad` binary at `./result/bin/`:++```sh+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ nix-build+```++#### Installing with `stack` using `nix`++`stack` can be used in conjunction with `nix` to install Termonad. `nix` will+handle installing system dependencies (like GTK and VTE), while `stack` will+handle compiling and installing Haskell packages.++You must have `nix` [installed](https://nixos.org/nix/download.html).++You will also need `stack` installed. You can do that with the following command:++```sh+$ nix-env -i stack+```++After `stack` is installed, you will need to clone Termonad and build it:++```+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ stack --nix install+```++This will install the `termonad` binary to `~/.local/bin/`.+ ### Windows (*currently no instructions available. please send a PR adding instructions if you get termonad to build.*)@@ -127,25 +196,38 @@ $ ~/.local/bin/termonad ``` -If you would like to configure termonad with your own settings, first you will-need to create a Haskell file called `~/.config/termonad/termonad.hs`. The-next section gives an example configuration file.+The following section describes the default keybindings. -If this file exists, when the `~/.local/bin/termonad` binary launches, it will-try to compile it. If it succeeds, it will create a separate binary file called-something like `~/.cache/termonad/termonad-linux-x86_64`. This binary file can-be thought of as your own personal Termonad, configured with all your own-settings.+If you would like to configure Termonad with your own settings, first you will+need to create a Haskell file called `~/.config/termonad/termonad.hs`. A following+section gives an example configuration file. +If this configuration file exists, when the `~/.local/bin/termonad` binary+launches, it will try to use GHC to compile the configuration file. If GHC+is able to successfully compile the configuration file, a separate binary will+be created called something like `~/.cache/termonad/termonad-linux-x86_64`.+This binary file can be thought of as your own personal Termonad, configured+with all your own settings.+ When you run `~/.local/bin/termonad`, it will re-exec `~/.cache/termonad/termonad-linux-x86_64` if it exists. However, there is one difficulty with this setup. In order for the `~/.local/bin/termonad` binary to be able to compile your-`~/.config/termonad/termonad.hs` file, it needs to know where GHC is, as well as-where all your Haskell packages live. This presents some difficulties that will-be discussed in a following section.+`~/.config/termonad/termonad.hs` configuration file, Termonad needs to know+where GHC is, as well as where all your Haskell packages live. This presents+some difficulties that will be discussed in a following section. +### Default Keybindings++Termonad provides the following default key bindings.++| Keybinding | Action |+|------------|--------|+| <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>t</kbd> | Open new tab. |+| <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>w</kbd> | Close tab. |+| <kbd>Alt</kbd> <kbd>(number key)</kbd> | Switch to tab `number`. For example, <kbd>Alt</kbd> <kbd>2</kbd> switches to tab 2. |+ ### Configuring Termonad The following is an example Termonad configuration file. You should save this to@@ -162,47 +244,64 @@ import Data.Colour.SRGB (Colour, sRGB24) import Termonad.App (defaultMain) import Termonad.Config- ( FontConfig, ShowScrollbar(ShowScrollbarAlways), cursorColor- , defaultFontConfig, defaultTMConfig, fontConfig, fontFamily- , fontSize, showScrollbar+ ( FontConfig, FontSize(FontSizePoints), Option(Set)+ , ShowScrollbar(ShowScrollbarAlways), defaultConfigOptions, defaultFontConfig+ , defaultTMConfig, fontConfig, fontFamily, fontSize, options, showScrollbar )+import Termonad.Config.Colour+ (ColourConfig, addColourExtension, createColourExtension, cursorBgColour+ , defaultColourConfig+ ) -- | This sets the color of the cursor in the terminal. -- -- This uses the "Data.Colour" module to define a dark-red color. -- There are many default colors defined in "Data.Colour.Names".-cursColor :: Colour Double-cursColor = sRGB24 204 0 0+cursBgColor :: Colour Double+cursBgColor = sRGB24 204 0 0 +-- | This sets the colors used for the terminal. We only specify the background+-- color of the cursor.+colConf :: ColourConfig (Colour Double)+colConf =+ defaultColourConfig+ { cursorBgColour = Set cursBgColor+ }+ -- | This defines the font for the terminal. fontConf :: FontConfig fontConf = defaultFontConfig { fontFamily = "DejaVu Sans Mono"- , fontSize = 13+ , fontSize = FontSizePoints 13 } main :: IO () main = do+ colExt <- createColourExtension colConf let termonadConf = defaultTMConfig- { cursorColor = cursColor- , fontConfig = fontConf- , showScrollbar = ShowScrollbarAlways+ { options =+ defaultConfigOptions+ { fontConfig = fontConf+ -- Make sure the scrollbar is always visible.+ , showScrollbar = ShowScrollbarAlways+ } }+ `addColourExtension` colExt defaultMain termonadConf ``` ### Compiling Local Settings -If you lauch Termonad by calling `~/.local/bin/termonad`, it will try to+If you launch Termonad by calling `~/.local/bin/termonad`, it will try to compile the `~/.config/termonad/termonad.hs` file if it exists. The problem is that `~/.local/bin/termonad` needs to be able to see GHC and the required Haskell libraries to be able to compile `~/.config/termonad/termonad.hs`. There are a couple solutions to this problem, listed in the sections below. -(These steps are definitely confusing, and I would love to figure out a better+(These steps are definitely confusing. I would love to figure out a better way to do this. Please submit an issue or PR if you have a good idea about how to fix this.) @@ -241,33 +340,15 @@ #### Running with `nix` -If you originally compiled Termonad with `nix`, you can use `nix` to create-an environment with GHC and specified Haskell libraries available.--There is a `.nix` file available you can use to do this:--[`.nix-helpers/running-termonad.nix`](./.nix-helpers/running-termonad.nix)--This file will give us an environment with `termonad`, GHC, and a few Haskell-libraries installed. You can enter this environment using `nix-shell`:--```sh-$ cd termonad/ # change to the termonad source code directory-$ nix-shell ./.nix-helpers/running-termonad.nix-```--From within this environment, you can run `termonad`. It will find the-`~/.config/termonad/termonad.hs` file and compile it, outputting the-`.cache/termonad/termonad-linux-x86_64` binary. Termonad will then re-exec-this binary.+Building Termonad with `nix` (by running `nix-build` in the top+directory) sets it up so that Termonad can see GHC. Termonad should be able+to compile the `~/.config/termonad/termonad.hs` file by default. -The problem with this is that `nix-shell` may change your environment variables-in ways you do not want. I recommend running `termonad` to get it to-recompile your `~/.config/termonad/termonad.hs` file, then exit the nix-shell environment and-rerun Termonad by calling it directly. Termonad will notice that-`~/.config/termonad/termonad.hs` hasn't been changed since-`~/.cache/termonad/termonad-linux-x86_64` has been recompiled, so it will-directly execute `~/.cache/termonad/termonad-linux-x86_64`.+If you're interested in how this works, or want to change which Haskell+packages are available from your `~/.config/termonad/termonad.hs` file, please+see the documentation in the+[`.nix-helpers/termonad-with-packages.nix`](./.nix-helpers/termonad-with-packages.nix)+file. ## Goals @@ -285,13 +366,13 @@ * flexible Most people only need a terminal emulator that lets you change the font-size,- cursor color, etc. They don't need tons of configuration options.- Termonad should be for people that like lots of configuration options.- Termonad should provide many hooks to allow the user to change it's behavior.+ cursor color, etc. They don't need tons of configuration options. Termonad+ should be for people that like lots of configuration options. Termonad+ should provide many hooks to allow the user full control over its behavior. * stable - Termonad should be able to be used as everyday as your main terminal+ Termonad should be able to be used everyday as your main terminal emulator. It should not crash for any reason. If you experience a crash, please file an issue or a pull request! @@ -302,6 +383,16 @@ certain data types or functions do. If you have a hard time understanding anything in the documentation, please submit an issue or PR. +## Where to get help++If you find a bug in Termonad, please either+[send a PR](https://github.com/cdepillabout/termonad/pulls) fixing it or create+an [issue](https://github.com/cdepillabout/termonad/issues) explaining it.++If you just need help with configuring Termonad, you can either join the+[Gitter room](https://gitter.im/termonad/Lobby) or+[#termonad on irc.freenode.net](https://webchat.freenode.net/).+ ## Contributions Contributions are highly appreciated. Termonad is currently missing many@@ -310,4 +401,5 @@ ## Maintainers -- [Dennis Gosnell](https://github.com/cdepillabout)+- [cdepillabout](https://github.com/cdepillabout)+- [LSLeary](https://github.com/LSLeary)
default.nix view
@@ -1,32 +1,23 @@-# This is the main nix file for termonad. It will just build the termonad binary.-# It can be built with the command `nix-build` in the main top directory.+# This is the main nix file for Termonad. It will build the `termonad`+# executable. It will place it in a "wrapped" environment so that Termonad can+# find GHC and a few Haskell libraries. This wrapped Termonad will be able to+# rebuild its configuration file (which should be located at+# `~/.config/termonad/termonad.hs`). #-# The termonad binary will be created at `result/bin/termonad`.--{ compiler ? "ghc843" }:--let- nixpkgs = import ./.nix-helpers/nixpkgs.nix;-- set-gi-vte-version = _: {- version = "2.91.19";- sha256 = "1hnhidjr7jh7i826lj6kdn264i592sfl5kwvymnpiycmcb37dd4y";- };-- set-gi-gtk-version = _: {- version = "3.0.24";- sha256 = "14cyj1acxs39avciyzqqb1qa5dr4my8rv3mfwv1kv92wa9a5i97v";- };+# Termonad can be built with the command `nix-build` in the main top+# directory.+#+# The `termonad` executable will be created at `result/bin/termonad`. With+# this default setup, you will be able to use the haskell packages `lens` and+# `colour` in your `~/.config/termonad/termonad.hs` file, as well as the+# Termonad package itself.+#+# If you want to install termonad into your environment, you can use `nix-env`+# from the main top directory:+#+# $ nix-env --file default.nix --install - allHaskellPackages = nixpkgs.pkgs.haskell.packages.${compiler}.override {- overrides = self: super: let lib = nixpkgs.pkgs.haskell.lib; in {- gi-gtk = lib.overrideCabal super.gi-gtk set-gi-gtk-version;- gi-vte = lib.overrideCabal (lib.addPkgconfigDepend (super.gi-vte.override { vte = nixpkgs.gnome3.vte; }) nixpkgs.gnome3.gtk) set-gi-vte-version;- };- };+{ compiler ? null, nixpkgs ? null }: -in+import .nix-helpers/termonad-with-packages.nix { inherit compiler nixpkgs; } -allHaskellPackages.callPackage .nix-helpers/termonad.nix {- inherit (nixpkgs.gnome3) gtk3;-}
+ example-config/ExampleColourExtension.hs view
@@ -0,0 +1,72 @@+-- | This is an example Termonad configuration that shows how to use the+-- 'ColourExtension' to set colours for your terminal. See the project-wide+-- README.md for how to use Termonad Haskell configuration scripts.++module Main where++import Termonad+ ( CursorBlinkMode(CursorBlinkModeOff), Option(Set)+ , ShowScrollbar(ShowScrollbarNever), TMConfig, confirmExit, cursorBlinkMode+ , defaultConfigOptions, defaultTMConfig, options, showMenu, showScrollbar+ , start+ )+import Termonad.Config.Colour+ ( Colour, ColourConfig, Palette(BasicPalette), addColourExtension+ , createColourExtension, cursorBgColour, defaultColourConfig, foregroundColour+ , palette, sRGB24+ )+import Termonad.Config.Vec (Vec((:*), EmptyVec), N8)+import Data.Colour.SRGB (Colour, sRGB24)++-- This is our main 'TMConfig'. It holds all of the non-colour settings+-- for Termonad.+--+-- This shows how a few settings can be changed.+myTMConfig :: TMConfig+myTMConfig =+ defaultTMConfig+ { options =+ defaultConfigOptions+ { showScrollbar = ShowScrollbarNever+ , confirmExit = False+ , showMenu = False+ , cursorBlinkMode = CursorBlinkModeOff+ }+ }++-- This is our 'ColourConfig'. It holds all of our colour-related settings.+myColourConfig :: ColourConfig (Colour Double)+myColourConfig =+ defaultColourConfig+ -- Set the cursor background colour. This is the normal colour of the+ -- cursor.+ { cursorBgColour = Set (sRGB24 120 80 110) -- purple+ -- Set the default foreground colour of text of the terminal.+ , foregroundColour = sRGB24 220 180 210 -- light pink+ -- Set the basic palette that has 8 colours.+ , palette = BasicPalette myStandardColours+ }+ where+ -- This is a length-indexed linked-list of colours.+ myStandardColours :: Vec N8 (Colour Double)+ myStandardColours =+ sRGB24 40 30 20 -- dark brown (used as background colour)+ :* sRGB24 180 30 20 -- red+ :* sRGB24 40 160 20 -- green+ :* sRGB24 180 160 20 -- dark yellow+ :* sRGB24 40 30 120 -- dark purple+ :* sRGB24 180 30 120 -- bright pink+ :* sRGB24 40 160 120 -- teal+ :* sRGB24 180 160 120 -- light brown+ :* EmptyVec++main :: IO ()+main = do+ -- First, create the colour extension based on 'myColourConfig'.+ myColourExt <- createColourExtension myColourConfig++ -- Update 'myTMConfig' with our colour extension.+ let newTMConfig = addColourExtension myTMConfig myColourExt++ -- Start Termonad with our updated 'TMConfig'.+ start newTMConfig
img/termonad-lambda.png view
binary file changed (23829 → 12047 bytes)
shell.nix view
@@ -1,16 +1,50 @@-# This is a file that allows you to jump into an environment to be able to build termonad.-# You can jump into this environment by running the command `nix-shell`.+# Running `nix-shell` in the same directory as this file will enter an+# environment in which you can easily hack on or build termonad. It provides:+# * Termonad's system dependencies.+# * GHC with all of termonad's haskell dependencies.+# * Local haddocks for those dependencies.+# * Hoogle with an index generated from those haddocks.+# * Cabal.+# * ghcid.+# * open-haddock. #-# This also installs cabal, so you should be able to build termonad by running `cabal new-build`.+# In this environment you should be able to e.g.+# * Build termonad:+# $ cabal new-build+# * Open a repl with access to the termonad libraries:+# $ cabal new-repl+# * Use `ghcid`:+# $ ghcid --command='cabal new-repl'+# * Open local haddocks for e.g. GI.Vte.Objects.Terminal:+# $ open-haddock GI.Vte.Objects.Terminal+# or for the gi-gtk package:+# $ open-haddock gi-gtk #-# In general, if you prefer to use `stack`, you probably won't use this file.+# If you pass nix-shell the arguments `--arg indexTermonad true`, then hoogle+# will also index the Termonad libraries, however this will mean the environment+# will need to be rebuilt every time the termonad source changes. -{ compiler ? "ghc843" }:+{ compiler ? null, indexTermonad ? false, nixpkgs ? null }: +with (import .nix-helpers/nixpkgs.nix { inherit compiler nixpkgs; });+ let- nixpkgs = import .nix-helpers/nixpkgs.nix;+ termonadEnv = haskellPackages.termonad.env;+ nativeBuildTools = with haskellPackages; [ cabal-install ghcid open-haddock ]; in -(import ./default.nix { inherit compiler; }).env.overrideAttrs (oldAttrs: rec {- nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [ nixpkgs.pkgs.haskell.packages.${compiler}.cabal-install ];-})+if indexTermonad+ then+ termonadEnv.overrideAttrs (oldAttrs: {+ nativeBuildInputs =+ oldAttrs.nativeBuildInputs +++ nativeBuildTools +++ [ (haskellPackages.ghcWithHoogle (haskellPackages: with haskellPackages; [ termonad ]))+ ];+ })+ else+ haskellPackages.shellFor {+ withHoogle = true;+ packages = haskellPackages: [ haskellPackages.termonad ];+ nativeBuildInputs = termonadEnv.nativeBuildInputs ++ nativeBuildTools;+ }
src/Termonad.hs view
@@ -1,7 +1,19 @@+-- | Module : Termonad+-- Description : Termonad+-- Copyright : (c) Dennis Gosnell, 2018+-- License : BSD3+-- Stability : experimental+-- Portability : POSIX+--+-- This module exposes termonad's basic configuration options, as well as 'defaultMain'.+--+-- If you want to configure Termonad, please take a look at "Termonad.Config".+ module Termonad ( defaultMain+ , start , module Config ) where -import Termonad.App (defaultMain)+import Termonad.App (defaultMain, start) import Termonad.Config as Config
src/Termonad/App.hs view
@@ -4,7 +4,9 @@ import Termonad.Prelude import Config.Dyre (defaultParams, projectName, realMain, showError, wrapMain)-import Control.Lens ((&), (^.), (.~))+import Control.Lens ((&), (.~), (^.))+import Data.FocusList (focusList, moveFromToFL, updateFocusFL)+import Data.Sequence (findIndexR) import GI.Gdk (castTo, managedForeignPtr, screenGetDefault) import GI.Gio ( ApplicationFlags(ApplicationFlagsFlagsNone)@@ -46,7 +48,6 @@ , onNotebookPageReordered , onNotebookSwitchPage , onWidgetDeleteEvent- , onWidgetDestroy , setWidgetMargin , styleContextAddProviderForScreen , widgetDestroy@@ -54,7 +55,6 @@ , widgetSetCanFocus , widgetShow , widgetShowAll- , windowClose , windowPresent , windowSetDefaultIconFromFile , windowSetTitle@@ -67,6 +67,7 @@ , fontDescriptionNew , fontDescriptionSetFamily , fontDescriptionSetSize+ , fontDescriptionSetAbsoluteSize ) import GI.Vte ( terminalCopyClipboard@@ -74,29 +75,30 @@ ) import Paths_termonad (getDataFileName)-import Termonad.Config- ( FontConfig(fontFamily, fontSize)- , TMConfig+import Termonad.Lenses+ ( lensConfirmExit , lensFontConfig+ , lensOptions+ , lensShowMenu+ , lensTMNotebookTabTerm+ , lensTMNotebookTabs+ , lensTMStateApp+ , lensTMStateConfig+ , lensTMStateNotebook+ , lensTerm )-import Termonad.FocusList (findFL, moveFromToFL, updateFocusFL) import Termonad.Gtk (appNew, objFromBuildUnsafe) import Termonad.Keys (handleKeyPress)-import Termonad.Term (createTerm, relabelTabs, termExitFocused)+import Termonad.Term (createTerm, relabelTabs, termExitFocused, setShowTabs) import Termonad.Types- ( TMNotebookTab+ ( FontConfig(fontFamily, fontSize)+ , FontSize(FontSizePoints, FontSizeUnits)+ , TMConfig+ , TMNotebookTab , TMState , TMState'(TMState)- , UserRequestedExit(UserRequestedExit, UserDidNotRequestExit) , getFocusedTermFromState- , getUserRequestedExit- , lensTMNotebookTabs- , lensTMNotebookTabTerm- , lensTMStateApp- , lensTMStateNotebook- , lensTerm , newEmptyTMState- , setUserRequestedExit , tmNotebookTabTermContainer , tmNotebookTabs , tmStateNotebook@@ -118,7 +120,7 @@ -- , " border-width: 200px;" , " background-color: #aaaaaa;" -- , " color: #ff0000;"- , " min-width: 4px;"+ -- , " min-width: 4px;" , "}" -- , "scrollbar trough {" -- , " -GtkRange-slider-width: 200px;"@@ -150,13 +152,17 @@ createFontDesc :: TMConfig -> IO FontDescription createFontDesc tmConfig = do fontDesc <- fontDescriptionNew- let fontConf = tmConfig ^. lensFontConfig+ let fontConf = tmConfig ^. lensOptions . lensFontConfig fontDescriptionSetFamily fontDesc (fontFamily fontConf)- fontDescriptionSetSize fontDesc (fromIntegral (fontSize fontConf) * SCALE)+ case fontSize fontConf of+ FontSizePoints points ->+ fontDescriptionSetSize fontDesc $ fromIntegral (points * fromIntegral SCALE)+ FontSizeUnits units ->+ fontDescriptionSetAbsoluteSize fontDesc $ units * fromIntegral SCALE pure fontDesc -compareScrolledWinAndTab :: ScrolledWindow -> a -> TMNotebookTab -> Bool-compareScrolledWinAndTab scrollWin _ flTab =+compareScrolledWinAndTab :: ScrolledWindow -> TMNotebookTab -> Bool+compareScrolledWinAndTab scrollWin flTab = let ScrolledWindow managedPtrFLTab = tmNotebookTabTermContainer flTab foreignPtrFLTab = managedForeignPtr managedPtrFLTab ScrolledWindow managedPtrScrollWin = scrollWin@@ -183,49 +189,65 @@ tmState & lensTMStateNotebook . lensTMNotebookTabs .~ newTabs -exitWithConfirmation :: TMState -> IO ()-exitWithConfirmation mvarTMState = do- respType <- exitWithConfirmationDialog mvarTMState- case respType of- ResponseTypeYes -> do- setUserRequestedExit mvarTMState- quit mvarTMState- _ -> pure ()--exitWithConfirmationDialog :: TMState -> IO ResponseType-exitWithConfirmationDialog mvarTMState = do+-- | Try to figure out whether Termonad should exit. This also used to figure+-- out if Termonad should close a given terminal.+--+-- This reads the 'confirmExit' setting from 'ConfigOptions' to check whether+-- the user wants to be notified when either Termonad or a given terminal is+-- about to be closed.+--+-- If 'confirmExit' is 'True', then a dialog is presented to the user asking+-- them if they really want to exit or close the terminal. Their response is+-- sent back as a 'ResponseType'.+--+-- If 'confirmExit' is 'False', then this function always returns+-- 'ResponseTypeYes'.+askShouldExit :: TMState -> IO ResponseType+askShouldExit mvarTMState = do tmState <- readMVar mvarTMState- let app = tmState ^. lensTMStateApp- win <- applicationGetActiveWindow app- dialog <- dialogNew- box <- dialogGetContentArea dialog- label <- labelNew (Just "There are still terminals running. Are you sure you want to exit?")- containerAdd box label- widgetShow label- setWidgetMargin label 10- void $- dialogAddButton- dialog- "No, do NOT exit"- (fromIntegral (fromEnum ResponseTypeNo))- void $- dialogAddButton- dialog- "Yes, exit"- (fromIntegral (fromEnum ResponseTypeYes))- windowSetTransientFor dialog win- res <- dialogRun dialog- widgetDestroy dialog- pure $ toEnum (fromIntegral res)+ let confirm = tmState ^. lensTMStateConfig . lensOptions . lensConfirmExit+ if confirm+ then confirmationDialogForExit tmState+ else pure ResponseTypeYes+ where+ -- Show the user a dialog telling them there are still terminals running and+ -- asking if they really want to exit.+ --+ -- Return the user's resposne as a 'ResponseType'.+ confirmationDialogForExit :: TMState' -> IO ResponseType+ confirmationDialogForExit tmState = do+ let app = tmState ^. lensTMStateApp+ win <- applicationGetActiveWindow app+ dialog <- dialogNew+ box <- dialogGetContentArea dialog+ label <-+ labelNew $+ Just+ "There are still terminals running. Are you sure you want to exit?"+ containerAdd box label+ widgetShow label+ setWidgetMargin label 10+ void $+ dialogAddButton+ dialog+ "No, do NOT exit"+ (fromIntegral (fromEnum ResponseTypeNo))+ void $+ dialogAddButton+ dialog+ "Yes, exit"+ (fromIntegral (fromEnum ResponseTypeYes))+ windowSetTransientFor dialog win+ res <- dialogRun dialog+ widgetDestroy dialog+ pure $ toEnum (fromIntegral res) -quit :: TMState -> IO ()-quit mvarTMState = do+-- | Force Termonad to exit without asking the user whether or not to do so.+forceQuit :: TMState -> IO ()+forceQuit mvarTMState = do tmState <- readMVar mvarTMState let app = tmState ^. lensTMStateApp- maybeWin <- applicationGetActiveWindow app- case maybeWin of- Nothing -> applicationQuit app- Just win -> windowClose win+ applicationQuit app setupTermonad :: TMConfig -> Application -> ApplicationWindow -> Gtk.Builder -> IO () setupTermonad tmConfig app win builder = do@@ -244,9 +266,9 @@ void $ onNotebookPageRemoved note $ \_ _ -> do pages <- notebookGetNPages note- when (pages == 0) $ do- setUserRequestedExit mvarTMState- quit mvarTMState+ if pages == 0+ then forceQuit mvarTMState+ else setShowTabs tmConfig note void $ onNotebookSwitchPage note $ \_ pageNum -> do maybeRes <- tryTakeMVar mvarTMState@@ -277,14 +299,15 @@ Just scrollWin -> do TMState{tmStateNotebook} <- readMVar mvarTMState let fl = tmStateNotebook ^. lensTMNotebookTabs- let maybeOldPosition = findFL (compareScrolledWinAndTab scrollWin) fl+ let maybeOldPosition =+ findIndexR (compareScrolledWinAndTab scrollWin) (focusList fl) case maybeOldPosition of Nothing -> fail $ "In setupTermonad, in callback for onNotebookPageReordered, " <> "the ScrolledWindow is not already in the FocusList.\n" <> "Don't know how to continue.\n"- Just (oldPos, _) -> do+ Just oldPos -> do updateFLTabPos mvarTMState oldPos (fromIntegral pageNum) relabelTabs mvarTMState @@ -300,8 +323,9 @@ applicationSetAccelsForAction app "app.closetab" ["<Shift><Ctrl>W"] quitAction <- simpleActionNew "quit" Nothing- void $ onSimpleActionActivate quitAction $ \_ ->- exitWithConfirmation mvarTMState+ void $ onSimpleActionActivate quitAction $ \_ -> do+ shouldExit <- askShouldExit mvarTMState+ when (shouldExit == ResponseTypeYes) $ forceQuit mvarTMState actionMapAddAction app quitAction applicationSetAccelsForAction app "app.quit" ["<Shift><Ctrl>Q"] @@ -323,24 +347,27 @@ void $ onSimpleActionActivate aboutAction (const $ showAboutDialog app) actionMapAddAction app aboutAction - menuBuilder <- builderNewFromString menuText $ fromIntegral (length menuText)- menuModel <- objFromBuildUnsafe menuBuilder "menubar" MenuModel- applicationSetMenubar app (Just menuModel)+ when (tmConfig ^. lensOptions . lensShowMenu) $ do+ menuBuilder <- builderNewFromString menuText $ fromIntegral (length menuText)+ menuModel <- objFromBuildUnsafe menuBuilder "menubar" MenuModel+ applicationSetMenubar app (Just menuModel) windowSetTitle win "Termonad" + -- This event will happen if the user requests that the top-level Termonad+ -- window be closed through their window manager. It will also happen+ -- normally when the user tries to close Termonad through normal methods,+ -- like clicking "Quit" or closing the last open terminal.+ --+ -- If you return 'True' from this callback, then Termonad will not exit.+ -- If you return 'False' from this callback, then Termonad will continue to+ -- exit. void $ onWidgetDeleteEvent win $ \_ -> do- userRequestedExit <- getUserRequestedExit mvarTMState- case userRequestedExit of- UserRequestedExit -> pure False- UserDidNotRequestExit -> do- respType <- exitWithConfirmationDialog mvarTMState- let stopOtherHandlers =- case respType of- ResponseTypeYes -> False- _ -> True- pure stopOtherHandlers- void $ onWidgetDestroy win $ quit mvarTMState+ shouldExit <- askShouldExit mvarTMState+ pure $+ case shouldExit of+ ResponseTypeYes -> False+ _ -> True widgetShowAll win widgetGrabFocus $ terminal ^. lensTerm@@ -366,6 +393,10 @@ appStartup :: Application -> IO () appStartup _app = pure () +-- | Run Termonad with the given 'TMConfig'.+--+-- Do not perform any of the recompilation operations that the 'defaultMain'+-- function does. start :: TMConfig -> IO () start tmConfig = do -- app <- appNew (Just "haskell.termonad") [ApplicationFlagsFlagsNone]@@ -375,6 +406,62 @@ void $ onApplicationActivate app (appActivate tmConfig app) void $ applicationRun app Nothing +-- | Run Termonad with the given 'TMConfig'.+--+-- This function will check if there is a @~\/.config\/termonad\/termonad.hs@ file+-- and a @~\/.cache\/termonad\/termonad-linux-x86_64@ binary. Termonad will+-- perform different actions based on whether or not these two files exist.+--+-- Here are the four different possible actions based on the existence of these+-- two files.+--+-- - @~\/.config\/termonad\/termonad.hs@ exists, @~\/.cache\/termonad\/termonad-linux-x86_64@ exists+--+-- The timestamps of these two files are checked. If the+-- @~\/.config\/termonad\/termonad.hs@ file has been modified after the+-- @~\/.cache\/termonad\/termonad-linux-x86_64@ binary, then Termonad will use+-- GHC to recompile the @~\/.config\/termonad\/termonad.hs@ file, producing a+-- new binary at @~\/.cache\/termonad\/termonad-linux-x86_64@. This new binary+-- will be re-executed. The 'TMConfig' passed to this 'defaultMain' will be+-- effectively thrown away.+--+-- If GHC fails to recompile the @~\/.config\/termonad\/termonad.hs@ file, then+-- Termonad will just execute 'start' with the 'TMConfig' passed in.+--+-- If the @~\/.cache\/termonad\/termonad-linux-x86_64@ binary has been modified+-- after the @~\/.config\/termonad\/termonad.hs@ file, then Termonad will+-- re-exec the @~\/.cache\/termonad\/termonad-linux-x86_64@ binary. The+-- 'TMConfig' passed to this 'defaultMain' will be effectively thrown away.+--+-- - @~\/.config\/termonad\/termonad.hs@ exists, @~\/.cache\/termonad\/termonad-linux-x86_64@ does not exist+--+-- Termonad will use GHC to recompile the @~\/.config\/termonad\/termonad.hs@+-- file, producing a new binary at @~\/.cache\/termonad\/termonad-linux-x86_64@.+-- This new binary will be re-executed. The 'TMConfig' passed to this+-- 'defaultMain' will be effectively thrown away.+--+-- If GHC fails to recompile the @~/.config/termonad/termonad.hs@ file, then+-- Termonad will just execute 'start' with the 'TMConfig' passed in.+--+-- - @~/.config/termonad/termonad.hs@ does not exist, @~/.cache/termonad/termonad-linux-x86_64@ exists+--+-- Termonad will ignore the @~/.cache/termonad/termonad-linux-x86_64@ binary+-- and just run 'start' with the 'TMConfig' passed to this function.+--+-- - @~/.config/termonad/termonad.hs@ does not exist, @~/.cache/termonad/termonad-linux-x86_64@ does not exist+--+-- Termonad will run 'start' with the 'TMConfig' passed to this function.+--+-- Other notes:+--+-- 1. That the locations of @~/.config/termonad/termonad.hs@ and+-- @~/.cache/termonad/termonad-linux-x86_64@ may differ depending on your+-- system.+--+-- 2. In your own @~/.config/termonad/termonad.hs@ file, you can use either+-- 'defaultMain' or 'start'. As long as you always execute the system-wide+-- @termonad@ binary (instead of the binary produced as+-- @~/.cache/termonad/termonad-linux-x86_64@), the effect should be the same. defaultMain :: TMConfig -> IO () defaultMain tmConfig = do let params =
src/Termonad/Config.hs view
@@ -1,59 +1,63 @@-{-# LANGUAGE TemplateHaskell #-}--module Termonad.Config where--import Termonad.Prelude--import Control.Lens (makeLensesFor)-import Data.Colour (Colour)-import Data.Colour.Names -- (grey)--data FontConfig = FontConfig- { fontFamily :: !Text- , fontSize :: !Int- } deriving (Eq, Show)--$(makeLensesFor- [ ("fontFamily", "lensFontFamily")- , ("fontSize", "lensFontSize")- ]- ''FontConfig- )--defaultFontConfig :: FontConfig-defaultFontConfig =- FontConfig- { fontFamily = "Monospace" -- or "DejaVu Sans Mono" or "Bitstream Vera Sans Mono Roman" or "Source Code Pro"- , fontSize = 12- }+-- | Module : Termonad.Config+-- Description : Termonad Configuration Options+-- Copyright : (c) Dennis Gosnell, 2018+-- License : BSD3+-- Stability : experimental+-- Portability : POSIX+--+-- This module exposes termonad's basic configuration options. To set these+-- options in your config, first ensure you've imported "Termonad".+--+-- Then for your main, apply 'Termonad.start' or 'Termonad.defaultMain' to a 'TMConfig' value.+-- We suggest you build such values by performing record updates on the+-- 'defaultTMConfig' rather than using the 'TMConfig' constructor, as the latter+-- is much more likely to break when there are changes to the 'TMConfig' type.+--+-- E.g.+--+-- @+-- -- Re-exports this module.+-- import "Termonad"+--+-- main :: IO ()+-- main = 'start' $ 'defaultTMConfig'+-- { 'showScrollbar' = 'ShowScrollbarNever'+-- , 'confirmExit' = False+-- , 'showMenu' = False+-- , 'cursorBlinkMode' = 'CursorBlinkModeOff'+-- }+-- @+--+-- Additional options can be found in the following modules.+--+-- * "Termonad.Config.Colour"+--+-- If you want to see an example configuration file, as well as an explanation+-- for how to use Termonad, see the Termonad+-- <https://github.com/cdepillabout/termonad#configuring-termonad README>. -data ShowScrollbar- = ShowScrollbarNever- | ShowScrollbarAlways- | ShowScrollbarIfNeeded- deriving (Eq, Show)+module Termonad.Config+ ( -- * Main Config Data Type+ TMConfig(..)+ , defaultTMConfig+ , ConfigOptions(..)+ , defaultConfigOptions+ , ConfigHooks(..)+ , defaultConfigHooks+ -- * Fonts+ , FontSize(..)+ , defaultFontSize+ , FontConfig(..)+ , defaultFontConfig+ -- * Misc+ , Option(..)+ , ShowScrollbar(..)+ , ShowTabBar(..)+ , CursorBlinkMode(..)+ ) where -data TMConfig = TMConfig- { fontConfig :: !FontConfig- , showScrollbar :: !ShowScrollbar- , cursorColor :: !(Colour Double)- , scrollbackLen :: !Integer- } deriving (Eq, Show)+import Termonad.Prelude hiding ((\\), index) -$(makeLensesFor- [ ("fontConfig", "lensFontConfig")- , ("showScrollbar", "lensShowScrollbar")- , ("cursorColor", "lensCursorColor")- , ("scrollbackLen", "lensScrollbackLen")- ]- ''TMConfig- )+import GI.Vte (CursorBlinkMode(..)) -defaultTMConfig :: TMConfig-defaultTMConfig =- TMConfig- { fontConfig = defaultFontConfig- , showScrollbar = ShowScrollbarIfNeeded- , cursorColor = lightgrey- , scrollbackLen = 10000- }+import Termonad.Types
+ src/Termonad/Config/Colour.hs view
@@ -0,0 +1,518 @@+{-# LANGUAGE TemplateHaskell #-}++-- | Module : Termonad.Config.Colour+-- Description : Termonad Configuration Colour Options+-- Copyright : (c) Dennis Gosnell, 2018+-- License : BSD3+-- Stability : experimental+-- Portability : POSIX+--+-- To use this config extension in your @~\/.config\/termonad\/termonad.hs@, first+-- import this module. Create a new 'ColourExtension' with the 'createColourExtension' function.+-- Then add the 'ColourExtension' to your 'TMConfig' with the 'addColourExtension' function.+--+-- See <https://github.com/cdepillabout/termonad/blob/master/example-config/ExampleColourExtension.hs this code> for a simple example.++module Termonad.Config.Colour+ ( -- * Colour Config+ ColourConfig(..)+ , defaultColourConfig+ -- ** Colour Config Lenses+ , lensCursorFgColour+ , lensCursorBgColour+ , lensForegroundColour+ , lensBackgroundColour+ , lensPalette+ -- * Colour Extension+ , ColourExtension(..)+ , createColourExtension+ , createDefColourExtension+ , addColourExtension+ , addColourConfig+ , colourHook+ , addColourHook+ -- * Palette+ , Palette(..)+ , defaultStandardColours+ , defaultLightColours+ , defaultColourCube+ , defaultGreyscale+ -- * Colour+ -- | Check out the "Data.Colour" module for more info about 'Colour'.+ , Colour+ , sRGB24+ , sRGB24show+ -- * Debugging and Internal Methods+ , showColourVec+ , showColourCube+ , paletteToList+ , coloursFromBits+ , cube+ ) where++import Termonad.Prelude hiding ((\\), index)++import Control.Lens ((%~), makeLensesFor)+import Data.Colour (Colour, black, affineCombo)+import Data.Colour.SRGB (RGB(RGB), toSRGB, sRGB24, sRGB24show)+import qualified Data.Foldable+import GI.Gdk (RGBA, newZeroRGBA, setRGBABlue, setRGBAGreen, setRGBARed)+import GI.Vte+ ( Terminal+ , terminalSetColors+ , terminalSetColorCursor+ , terminalSetColorCursorForeground+--, terminalSetColorBackground+ , terminalSetColorForeground+ )+import Text.Show (showString)++import Termonad.Config.Vec+import Termonad.Lenses (lensCreateTermHook, lensHooks)+import Termonad.Types+ ( Option(Unset)+ , TMConfig+ , TMState+ , whenSet+ )++-------------------+-- Colour Config --+-------------------++-- | This is the color palette to use for the terminal. Each data constructor+-- lets you set progressively more colors. These colors are used by the+-- terminal to render+-- <https://en.wikipedia.org/wiki/ANSI_escape_code#Colors ANSI escape color codes>.+--+-- There are 256 total terminal colors. 'BasicPalette' lets you set the first 8,+-- 'ExtendedPalette' lets you set the first 16, 'ColourCubePalette' lets you set+-- the first 232, and 'FullPalette' lets you set all 256.+--+-- The first 8 colors codes are the standard colors. The next 8 are the+-- extended (light) colors. The next 216 are a full color cube. The last 24 are a+-- grey scale.+--+-- The following image gives an idea of what each individual color looks like:+--+-- <<https://raw.githubusercontent.com/cdepillabout/termonad/master/img/terminal-colors.png>>+--+-- This picture does not exactly match up with Termonad's default colors, but it gives an+-- idea of what each block of colors represents.+--+-- You can use 'defaultStandardColours', 'defaultLightColours',+-- 'defaultColourCube', and 'defaultGreyscale' as a starting point to+-- customize the colors. The only time you'd need to use a constructor other+-- than 'NoPalette' is when you want to customize the default colors.+-- That is to say, using 'FullPalette' with all the defaults should give you the+-- same result as using 'NoPalette'.+data Palette c+ = NoPalette+ -- ^ Don't set any colors and just use the default from VTE. This is a black+ -- background with light grey text.+ | BasicPalette !(Vec N8 c)+ -- ^ Set the colors from the standard colors.+ | ExtendedPalette !(Vec N8 c) !(Vec N8 c)+ -- ^ Set the colors from the extended (light) colors (as well as standard colors).+ | ColourCubePalette !(Vec N8 c) !(Vec N8 c) !(Matrix '[N6, N6, N6] c)+ -- ^ Set the colors from the color cube (as well as the standard colors and+ -- extended colors).+ | FullPalette !(Vec N8 c) !(Vec N8 c) !(Matrix '[N6, N6, N6] c) !(Vec N24 c)+ -- ^ Set the colors from the grey scale (as well as the standard colors,+ -- extended colors, and color cube).+ deriving (Eq, Show, Functor, Foldable)++-- | Convert a 'Palette' to a list of colors. This is helpful for debugging.+paletteToList :: Palette c -> [c]+paletteToList = Data.Foldable.toList++-- | Create a vector of colors based on input bits.+--+-- This is used to derive 'defaultStandardColours' and 'defaultLightColours'.+--+-- >>> coloursFromBits 192 0 == defaultStandardColours+-- True+--+-- >>> coloursFromBits 192 63 == defaultLightColours+-- True+--+-- In general, as an end-user, you shouldn't need to use this.+coloursFromBits :: forall b. (Ord b, Floating b) => Word8 -> Word8 -> Vec N8 (Colour b)+coloursFromBits scale offset = genVec_ createElem+ where+ createElem :: Fin N8 -> Colour b+ createElem finN =+ let red = cmp 0 finN+ green = cmp 1 finN+ blue = cmp 2 finN+ color = sRGB24 red green blue+ in color++ cmp :: Int -> Fin N8 -> Word8+ cmp i = (offset +) . (scale *) . fromIntegral . bit i . toIntFin++ bit :: Int -> Int -> Int+ bit m i = i `div` (2 ^ m) `mod` 2++-- | A 'Vec' of standard colors. Default value for 'BasicPalette'.+--+-- >>> showColourVec defaultStandardColours+-- ["#000000","#c00000","#00c000","#c0c000","#0000c0","#c000c0","#00c0c0","#c0c0c0"]+defaultStandardColours :: (Ord b, Floating b) => Vec N8 (Colour b)+defaultStandardColours = coloursFromBits 192 0++-- | A 'Vec' of extended (light) colors. Default value for 'ExtendedPalette'.+--+-- >>> showColourVec defaultLightColours+-- ["#3f3f3f","#ff3f3f","#3fff3f","#ffff3f","#3f3fff","#ff3fff","#3fffff","#ffffff"]+defaultLightColours :: (Ord b, Floating b) => Vec N8 (Colour b)+defaultLightColours = coloursFromBits 192 63++-- | A helper function for showing all the colors in 'Vec' of colors.+showColourVec :: forall n. Vec n (Colour Double) -> [String]+showColourVec = fmap sRGB24show . Data.Foldable.toList++-- | Specify a colour cube with one colour vector for its displacement and three+-- colour vectors for its edges. Produces a uniform 6x6x6 grid bounded by+-- and orthognal to the faces.+cube ::+ forall b. Fractional b+ => Colour b+ -> Vec N3 (Colour b)+ -> Matrix '[ N6, N6, N6] (Colour b)+cube d (i :* j :* k :* EmptyVec) =+ genMatrix_ $+ \(x :< y :< z :< EmptyHList) ->+ affineCombo [(1, d), (coef x, i), (coef y, j), (coef z, k)] black+ where+ coef :: Fin N6 -> b+ coef fin = fromIntegral (toIntFin fin) / 5++-- | A matrix of a 6 x 6 x 6 color cube. Default value for 'ColourCubePalette'.+--+-- >>> putStrLn $ pack $ showColourCube defaultColourCube+-- [ [ #000000, #00005f, #000087, #0000af, #0000d7, #0000ff+-- , #005f00, #005f5f, #005f87, #005faf, #005fd7, #005fff+-- , #008700, #00875f, #008787, #0087af, #0087d7, #0087ff+-- , #00af00, #00af5f, #00af87, #00afaf, #00afd7, #00afff+-- , #00d700, #00d75f, #00d787, #00d7af, #00d7d7, #00d7ff+-- , #00ff00, #00ff5f, #00ff87, #00ffaf, #00ffd7, #00ffff+-- ]+-- , [ #5f0000, #5f005f, #5f0087, #5f00af, #5f00d7, #5f00ff+-- , #5f5f00, #5f5f5f, #5f5f87, #5f5faf, #5f5fd7, #5f5fff+-- , #5f8700, #5f875f, #5f8787, #5f87af, #5f87d7, #5f87ff+-- , #5faf00, #5faf5f, #5faf87, #5fafaf, #5fafd7, #5fafff+-- , #5fd700, #5fd75f, #5fd787, #5fd7af, #5fd7d7, #5fd7ff+-- , #5fff00, #5fff5f, #5fff87, #5fffaf, #5fffd7, #5fffff+-- ]+-- , [ #870000, #87005f, #870087, #8700af, #8700d7, #8700ff+-- , #875f00, #875f5f, #875f87, #875faf, #875fd7, #875fff+-- , #878700, #87875f, #878787, #8787af, #8787d7, #8787ff+-- , #87af00, #87af5f, #87af87, #87afaf, #87afd7, #87afff+-- , #87d700, #87d75f, #87d787, #87d7af, #87d7d7, #87d7ff+-- , #87ff00, #87ff5f, #87ff87, #87ffaf, #87ffd7, #87ffff+-- ]+-- , [ #af0000, #af005f, #af0087, #af00af, #af00d7, #af00ff+-- , #af5f00, #af5f5f, #af5f87, #af5faf, #af5fd7, #af5fff+-- , #af8700, #af875f, #af8787, #af87af, #af87d7, #af87ff+-- , #afaf00, #afaf5f, #afaf87, #afafaf, #afafd7, #afafff+-- , #afd700, #afd75f, #afd787, #afd7af, #afd7d7, #afd7ff+-- , #afff00, #afff5f, #afff87, #afffaf, #afffd7, #afffff+-- ]+-- , [ #d70000, #d7005f, #d70087, #d700af, #d700d7, #d700ff+-- , #d75f00, #d75f5f, #d75f87, #d75faf, #d75fd7, #d75fff+-- , #d78700, #d7875f, #d78787, #d787af, #d787d7, #d787ff+-- , #d7af00, #d7af5f, #d7af87, #d7afaf, #d7afd7, #d7afff+-- , #d7d700, #d7d75f, #d7d787, #d7d7af, #d7d7d7, #d7d7ff+-- , #d7ff00, #d7ff5f, #d7ff87, #d7ffaf, #d7ffd7, #d7ffff+-- ]+-- , [ #ff0000, #ff005f, #ff0087, #ff00af, #ff00d7, #ff00ff+-- , #ff5f00, #ff5f5f, #ff5f87, #ff5faf, #ff5fd7, #ff5fff+-- , #ff8700, #ff875f, #ff8787, #ff87af, #ff87d7, #ff87ff+-- , #ffaf00, #ffaf5f, #ffaf87, #ffafaf, #ffafd7, #ffafff+-- , #ffd700, #ffd75f, #ffd787, #ffd7af, #ffd7d7, #ffd7ff+-- , #ffff00, #ffff5f, #ffff87, #ffffaf, #ffffd7, #ffffff+-- ]+-- ]+defaultColourCube :: (Ord b, Floating b) => Matrix '[N6, N6, N6] (Colour b)+defaultColourCube =+ genMatrix_ $ \(x :< y :< z :< EmptyHList) -> sRGB24 (cmp x) (cmp y) (cmp z)+ where+ cmp :: Fin N6 -> Word8+ cmp i =+ let i' = fromIntegral (toIntFin i)+ in signum i' * 55 + 40 * i'++-- | Helper function for showing all the colors in a color cube. This is used+-- for debugging.+showColourCube :: Matrix '[N6, N6, N6] (Colour Double) -> String+showColourCube matrix =+ -- TODO: This function will only work with a 6x6x6 matrix, but it could be+ -- generalized to work with any Rank-3 matrix.+ let itemList = Data.Foldable.toList matrix+ in showSColourCube itemList ""+ where+ showSColourCube :: [Colour Double] -> String -> String+ showSColourCube itemList =+ showString "[ " .+ showSquare 0 itemList .+ showString ", " .+ showSquare 1 itemList .+ showString ", " .+ showSquare 2 itemList .+ showString ", " .+ showSquare 3 itemList .+ showString ", " .+ showSquare 4 itemList .+ showString ", " .+ showSquare 5 itemList .+ showString "]"++ showSquare :: Int -> [Colour Double] -> String -> String+ showSquare i colours =+ showString "[ " .+ showRow i 0 colours .+ showString ", " .+ showRow i 1 colours .+ showString ", " .+ showRow i 2 colours .+ showString ", " .+ showRow i 3 colours .+ showString ", " .+ showRow i 4 colours .+ showString ", " .+ showRow i 5 colours .+ showString "]\n"++ showRow :: Int -> Int -> [Colour Double] -> String -> String+ showRow i j colours =+ showCol (headEx $ drop (i * 36 + j * 6 + 0) colours) .+ showString ", " .+ showCol (headEx $ drop (i * 36 + j * 6 + 1) colours) .+ showString ", " .+ showCol (headEx $ drop (i * 36 + j * 6 + 2) colours) .+ showString ", " .+ showCol (headEx $ drop (i * 36 + j * 6 + 3) colours) .+ showString ", " .+ showCol (headEx $ drop (i * 36 + j * 6 + 4) colours) .+ showString ", " .+ showCol (headEx $ drop (i * 36 + j * 6 + 5) colours) .+ showString "\n "++ showCol :: Colour Double -> String -> String+ showCol col str = sRGB24show col <> str++-- | A 'Vec' of a grey scale. Default value for 'FullPalette'.+--+-- >>> showColourVec defaultGreyscale+-- ["#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a8a8a8","#b2b2b2","#bcbcbc","#c6c6c6","#d0d0d0","#dadada","#e4e4e4","#eeeeee"]+defaultGreyscale :: (Ord b, Floating b) => Vec N24 (Colour b)+defaultGreyscale = genVec_ $ \n ->+ let l = 8 + 10 * fromIntegral (toIntFin n)+ in sRGB24 l l l++-- | The configuration for the colors used by Termonad.+--+-- 'foregroundColour' and 'backgroundColour' allow you to set the color of the+-- foreground text and background of the terminal (although see the __WARNING__+-- below). Most people use a black background and a light foreground for their+-- terminal, so this is the default.+--+-- 'palette' allows you to set the full color palette used by the terminal.+-- See 'Palette' for more information.+--+-- If you want to use a terminal with a white (or light) background and a black+-- foreground, it may be a good idea to change some of the colors in the+-- 'Palette' as well.+--+-- (__WARNING__: Currently due to issues either with VTE or the bindings generated for+-- Haskell, background colour cannot be set independently of the palette.+-- The @backgroundColour@ field will be ignored and the 0th colour in the+-- palette (by default black) will be used as the background colour. See+-- <https://github.com/cdepillabout/termonad/issues/29 this issue>.+--+-- VTE works as follows: if you don't explicitly set a background or foreground color,+-- it takes the 0th colour from the 'palette' to be the background color, and the 7th+-- colour from the 'palette' to be the foreground color. If you notice oddities with+-- colouring in certain applications, it may be helpful to make sure that these+-- 'palette' colours match up with the 'backgroundColour' and 'foregroundColour' you+-- have set.)+--+-- 'cursorFgColour' and 'cursorBgColour' allow you to set the foreground color+-- of the text under the cursor, as well as the color of the cursor itself.+--+-- Termonad will behave differently depending on the combination+-- 'cursorFgColour' and 'cursorBgColour' being 'Set' vs. 'Unset'.+-- Here is the summary of the different possibilities:+--+-- * 'cursorFgColour' is 'Set' and 'cursorBgColour' is 'Set'+--+-- The foreground and background colors of the cursor are as you have set.+--+-- * 'cursorFgColour' is 'Set' and 'cursorBgColour' is 'Unset'+--+-- The cursor background color turns completely black so that it is not+-- visible. The foreground color of the cursor is the color that you have+-- 'Set'. This ends up being mostly unusable, so you are recommended to+-- always 'Set' 'cursorBgColour' when you have 'Set' 'cursorFgColour'.+--+-- * 'cursorFgColour' is 'Unset' and 'cursorBgColour' is 'Set'+--+-- The cursor background color becomes the color you 'Set', while the cursor+-- foreground color doesn't change from the letter it is over. For instance,+-- imagine there is a letter on the screen with a black background and a+-- green foreground. If you bring the cursor overtop of it, the cursor+-- background will be the color you have 'Set', while the cursor foreground+-- will be green.+--+-- This is completely usable, but is slightly annoying if you place the cursor+-- over a letter with the same foreground color as the cursor's background+-- color, because the letter will not be readable. For instance, imagine you+-- have set your cursor background color to red, and somewhere on the screen+-- there is a letter with a black background and a red foreground. If you move+-- your cursor over the letter, the background of the cursor will be red (as+-- you have set), and the cursor foreground will be red (to match the original+-- foreground color of the letter). This will make it so you can't+-- actually read the letter, because the foreground and background are both+-- red.+--+-- * 'cursorFgColour' is 'Unset' and 'cursorBgColour' is 'Unset'+--+-- This combination makes the cursor inverse of whatever text it is over.+-- If your cursor is over red text with a black background, the cursor+-- background will be red and the cursor foreground will be black.+--+-- This is the default.+--+-- See 'defaultColourConfig' for the defaults for 'ColourConfig' used in Termonad.+data ColourConfig c = ColourConfig+ { cursorFgColour :: !(Option c) -- ^ Foreground color of the cursor. This is+ -- the color of the text that the cursor is+ -- over.+ , cursorBgColour :: !(Option c) -- ^ Background color of the cursor. This is+ -- the color of the cursor itself.+ , foregroundColour :: !c -- ^ Color of the default default foreground text in+ -- the terminal.+ , backgroundColour :: !c -- ^ Background color for the terminal, however, See+ -- the __WARNING__ above.+ , palette :: !(Palette c) -- ^ Color palette for the terminal. See 'Palette'.+ } deriving (Eq, Show, Functor)++-- | Default setting for a 'ColourConfig'. The cursor colors are left at their+-- default for VTE. The foreground text for the terminal is grey and the+-- background of the terminal is black. The palette is left as the default for+-- VTE.+--+-- >>> let fgGrey = sRGB24 192 192 192+-- >>> let bgBlack = sRGB24 0 0 0+-- >>> let defCC = ColourConfig { cursorFgColour = Unset, cursorBgColour = Unset, foregroundColour = fgGrey, backgroundColour = bgBlack, palette = NoPalette }+-- >>> defaultColourConfig == defCC+-- True+defaultColourConfig :: ColourConfig (Colour Double)+defaultColourConfig = ColourConfig+ { cursorFgColour = Unset+ , cursorBgColour = Unset+ , foregroundColour = sRGB24 192 192 192+ , backgroundColour = black+ , palette = NoPalette+ }++$(makeLensesFor+ [ ("cursorFgColour", "lensCursorFgColour")+ , ("cursorBgColour", "lensCursorBgColour")+ , ("foregroundColour", "lensForegroundColour")+ , ("backgroundColour", "lensBackgroundColour")+ , ("palette", "lensPalette")+ ]+ ''ColourConfig+ )++------------------------------+-- ConfigExtension Instance --+------------------------------++-- | Extension that allows setting colors for terminals in Termonad.+data ColourExtension = ColourExtension+ { colourExtConf :: MVar (ColourConfig (Colour Double))+ -- ^ 'MVar' holding the current 'ColourConfig'. This could potentially be+ -- passed to other extensions or user code. This would allow changing the+ -- colors for new terminals in realtime.+ , colourExtCreateTermHook :: TMState -> Terminal -> IO ()+ -- ^ The 'createTermHook' used by the 'ColourExtension'. This sets the+ -- colors for a new terminal based on the 'ColourConfig' in 'colourExtConf'.+ }++-- | The default 'createTermHook' for 'colourExtCreateTermHook'. Set the colors+-- for a terminal based on the given 'ColourConfig'.+colourHook :: MVar (ColourConfig (Colour Double)) -> TMState -> Terminal -> IO ()+colourHook mvarColourConf _ vteTerm = do+ colourConf <- readMVar mvarColourConf+ terminalSetColors vteTerm Nothing Nothing . Just+ =<< traverse toRGBA (paletteToList . palette $ colourConf)+ -- PR #28 / issue #29: Setting the background colour is broken in gi-vte or VTE. If+ -- this next line is called, then you are no longer able to set the+ -- background color using the palette.+ -- terminalSetColorBackground vteTerm =<< toRGBA (backgroundColour colourConf)+ terminalSetColorForeground vteTerm =<< toRGBA (foregroundColour colourConf)+ let optPerform setC cField = whenSet (cField colourConf) $ \c ->+ setC vteTerm . Just =<< toRGBA c+ optPerform terminalSetColorCursor cursorBgColour+ optPerform terminalSetColorCursorForeground cursorFgColour+ where+ toRGBA :: Colour Double -> IO RGBA+ toRGBA colour = do+ let RGB red green blue = toSRGB colour+ rgba <- newZeroRGBA+ setRGBARed rgba red+ setRGBAGreen rgba green+ setRGBABlue rgba blue+ pure rgba++-- | Create a 'ColourExtension' based on a given 'ColourConfig'.+--+-- Most users will want to use this.+createColourExtension :: ColourConfig (Colour Double) -> IO ColourExtension+createColourExtension conf = do+ mvarConf <- newMVar conf+ pure $+ ColourExtension+ { colourExtConf = mvarConf+ , colourExtCreateTermHook = colourHook mvarConf+ }++-- | Create a 'ColourExtension' based on 'defaultColourConfig'.+--+-- Note that this is not needed if you just want to use the default colors for+-- Termonad. However, if you want to pass around the 'MVar' 'ColourConfig' for+-- extensions to use, then you may need this function.+createDefColourExtension :: IO ColourExtension+createDefColourExtension = createColourExtension defaultColourConfig++-- | Add a given 'ColourConfig' to a 'TMConfig'. This adds 'colourHook' to the+-- 'createTermHook' in 'TMConfig'.+addColourConfig :: TMConfig -> ColourConfig (Colour Double) -> IO TMConfig+addColourConfig tmConf colConf = do+ ColourExtension _ newHook <- createColourExtension colConf+ let newTMConf = tmConf & lensHooks . lensCreateTermHook %~ addColourHook newHook+ pure newTMConf++-- | This is similar to 'addColourConfig', but can be used on a+-- 'ColourExtension' created with 'createColourExtension'.+addColourExtension :: TMConfig -> ColourExtension -> TMConfig+addColourExtension tmConf (ColourExtension _ newHook) =+ tmConf & lensHooks . lensCreateTermHook %~ addColourHook newHook++-- | This function shows how to combine 'createTermHook's.+--+-- This first runs the old hook, followed by the new hook.+--+-- This is used internally by 'addColourConfig' and 'addColourExtension'.+addColourHook+ :: (TMState -> Terminal -> IO ()) -- ^ New hook+ -> (TMState -> Terminal -> IO ()) -- ^ Old hook+ -> TMState+ -> Terminal+ -> IO ()+addColourHook newHook oldHook tmState term = do+ oldHook tmState term+ newHook tmState term
+ src/Termonad/Config/Vec.hs view
@@ -0,0 +1,564 @@+{-# LANGUAGE RoleAnnotations #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeInType #-}+{-# LANGUAGE UndecidableInstances #-}++-- | Module : Termonad.Config.Vec+-- Description : A small library of dependent types+-- Copyright : (c) Dennis Gosnell, 2018+-- License : BSD3+-- Stability : experimental+-- Portability : POSIX+--+-- This is a small library of dependent types. It provides indexed types like+-- 'Fin', 'Vec', and 'Matrix'.+--+-- This is mainly used in Termonad for "Termonad.Config.Colour" to represent+-- length-indexed colour lists.+--+-- This module implements a subset of the functionality from the abandoned+-- <http://hackage.haskell.org/package/type-combinators type-combinators> library.+-- Ideally this module would be split out to a separate package.+-- If you're interested in working on something like this, please see+-- <https://github.com/cdepillabout/termonad/issues/70 this issue> on Github.++module Termonad.Config.Vec+ -- ( Fin+ -- , I(I)+ -- , M(M)+ -- , N3+ -- , N24+ -- , N6+ -- , N8+ -- , Prod((:<), Ø)+ -- , Range+ -- , Vec+ -- , VecT((:+), (:*), ØV, EmptyV)+ -- , fin+ -- , genMatrix_+ -- , setSubmatrix+ -- , genVec_+ -- , vSetAt'+ -- )+ where++import Termonad.Prelude hiding ((\\), index)++import Data.Distributive (Distributive(distribute))+import qualified Data.Foldable as Data.Foldable+import Data.Functor.Rep (Representable(..), apRep, bindRep, distributeRep, pureRep)+import Data.Kind (Type)+import Data.Singletons.Prelude+import Data.Singletons.TH+import Text.Show (showParen, showString)++--------------------------+-- Misc VecT Operations --+--------------------------++-- TODO: These could be implemented?++-- data Range n l m = Range (IFin ('S n) l) (IFin ('S n) (l + m))+-- deriving (Show, Eq)++-- instance (Known (IFin ('S n)) l, Known (IFin ('S n)) (l + m))+-- => Known (Range n l) m where+-- type KnownC (Range n l) m+-- = (Known (IFin ('S n)) l, Known (IFin ('S n)) (l + m))+-- known = Range known known++-- updateRange :: Range n l m -> (Fin m -> f a -> f a) -> VecT n f a -> VecT n f a+-- updateRange = \case+-- Range IFZ IFZ -> \_ -> id+-- Range (IFS l) (IFS m) -> \f -> onTail (updateRange (Range l m) f) \\ m+-- Range IFZ (IFS m) -> \f -> onTail (updateRange (Range IFZ m) $ f . FS)+-- . onHead (f FZ) \\ m++-- setRange :: Range n l m -> VecT m f a -> VecT n f a -> VecT n f a+-- setRange r nv = updateRange r (\i _ -> index i nv)++-- updateSubmatrix+-- :: (ns ~ Fsts3 nlms, ms ~ Thds3 nlms)+-- => HList (Uncur3 Range) nlms -> (HList Fin ms -> a -> a) -> M ns a -> M ns a+-- updateSubmatrix = \case+-- Ø -> \f -> (f Ø <$>)+-- Uncur3 r :< rs -> \f -> onMatrix . updateRange r $ \i ->+-- asM . updateSubmatrix rs $ f . (i :<)++-- setSubmatrix+-- :: (ns ~ Fsts3 nlms, ms ~ Thds3 nlms)+-- => HList (Uncur3 Range) nlms -> M ms a -> M ns a -> M ns a+-- setSubmatrix rs sm = updateSubmatrix rs $ \is _ -> indexMatrix is sm++-----------+-- Peano --+-----------++$(singletons [d|++ data Peano = Z | S Peano deriving (Eq, Ord, Show)++ addPeano :: Peano -> Peano -> Peano+ addPeano Z a = a+ addPeano (S a) b = S (addPeano a b)++ subtractPeano :: Peano -> Peano -> Peano+ subtractPeano Z _ = Z+ subtractPeano a Z = a+ subtractPeano (S a) (S b) = subtractPeano a b++ multPeano :: Peano -> Peano -> Peano+ multPeano Z _ = Z+ multPeano (S a) b = addPeano (multPeano a b) b++ n0 :: Peano+ n0 = Z++ n1 :: Peano+ n1 = S n0++ n2 :: Peano+ n2 = S n1++ n3 :: Peano+ n3 = S n2++ n4 :: Peano+ n4 = S n3++ n5 :: Peano+ n5 = S n4++ n6 :: Peano+ n6 = S n5++ n7 :: Peano+ n7 = S n6++ n8 :: Peano+ n8 = S n7++ n9 :: Peano+ n9 = S n8++ n10 :: Peano+ n10 = S n9++ n24 :: Peano+ n24 = multPeano n4 n6++ instance Num Peano where+ (+) = addPeano++ (-) = subtractPeano++ (*) = multPeano++ abs = id++ signum Z = Z+ signum (S _) = S Z++ fromInteger n =+ if n < 0+ then error "Num Peano fromInteger: n is negative"+ else+ if n == 0 then Z else S (fromInteger (n - 1))+ |])++---------+-- Fin --+---------++data Fin :: Peano -> Type where+ FZ :: forall (n :: Peano). Fin ('S n)+ FS :: forall (n :: Peano). !(Fin n) -> Fin ('S n)++deriving instance Eq (Fin n)+deriving instance Ord (Fin n)+deriving instance Show (Fin n)++toIntFin :: Fin n -> Int+toIntFin FZ = 0+toIntFin (FS x) = succ $ toIntFin x++data instance Sing (z :: Fin n) where+ SFZ :: Sing 'FZ+ SFS :: Sing x -> Sing ('FS x)++instance SingI 'FZ where+ sing = SFZ++instance SingI n => SingI ('FS n) where+ sing = SFS sing++instance SingKind (Fin n) where+ type Demote (Fin n) = Fin n+ fromSing :: forall (a :: Fin n). Sing a -> Fin n+ fromSing SFZ = FZ+ fromSing (SFS fin) = FS (fromSing fin)++ toSing :: Fin n -> SomeSing (Fin n)+ toSing FZ = SomeSing SFZ+ toSing (FS fin) =+ case toSing fin of+ SomeSing n -> SomeSing (SFS n)++instance Show (Sing 'FZ) where+ show SFZ = "SFZ"++instance Show (Sing n) => Show (Sing ('FS n)) where+ showsPrec d (SFS n) =+ showParen (d > 10) $+ showString "SFS " . showsPrec 11 n++----------+-- IFin --+----------++data IFin :: Peano -> Peano -> Type where+ IFZ :: forall (n :: Peano). IFin ('S n) 'Z+ IFS :: forall (n :: Peano) (m :: Peano). !(IFin n m) -> IFin ('S n) ('S m)++deriving instance Eq (IFin x y)+deriving instance Ord (IFin x y)+deriving instance Show (IFin x y)++toFinIFin :: IFin n m -> Fin n+toFinIFin IFZ = FZ+toFinIFin (IFS n) = FS (toFinIFin n)++toIntIFin :: IFin n m -> Int+toIntIFin = toIntFin . toFinIFin++data instance Sing (z :: IFin n m) where+ SIFZ :: Sing 'IFZ+ SIFS :: Sing x -> Sing ('IFS x)++instance SingI 'IFZ where+ sing = SIFZ++instance SingI n => SingI ('IFS n) where+ sing = SIFS sing++instance SingKind (IFin n m) where+ type Demote (IFin n m) = IFin n m+ fromSing :: forall (a :: IFin n m). Sing a -> IFin n m+ fromSing SIFZ = IFZ+ fromSing (SIFS fin) = IFS (fromSing fin)++ toSing :: IFin n m -> SomeSing (IFin n m)+ toSing IFZ = SomeSing SIFZ+ toSing (IFS fin) =+ case toSing fin of+ SomeSing n -> SomeSing (SIFS n)++instance Show (Sing 'IFZ) where+ show SIFZ = "SIFZ"++instance Show (Sing n) => Show (Sing ('IFS n)) where+ showsPrec d (SIFS n) =+ showParen (d > 10) $+ showString "SIFS " . showsPrec 11 n++-----------+-- HList --+-----------++data HList :: (k -> Type) -> [k] -> Type where+ EmptyHList :: HList f '[]+ (:<) :: forall (f :: k -> Type) (a :: k) (as :: [k]). f a -> HList f as -> HList f (a ': as)++infixr 6 :<++-- | Data constructor for ':<'.+pattern ConsHList :: (f a :: Type) -> HList f as -> HList f (a ': as)+pattern ConsHList fa hlist = fa :< hlist++---------+-- Vec --+---------++data Vec (n :: Peano) :: Type -> Type where+ EmptyVec :: Vec 'Z a+ (:*) :: !a -> !(Vec n a) -> Vec ('S n) a+ deriving anyclass MonoFoldable++infixr 6 :*++-- | Data constructor for ':*'.+pattern ConsVec :: (a :: Type) -> Vec n a -> Vec ('S n) a+pattern ConsVec a vec = a :* vec++deriving instance Eq a => Eq (Vec n a)+deriving instance Ord a => Ord (Vec n a)+deriving instance Show a => Show (Vec n a)++deriving instance Functor (Vec n)+deriving instance Foldable (Vec n)++instance MonoFunctor (Vec n a)++instance SingI n => MonoPointed (Vec n a)++instance SingI n => Applicative (Vec n) where+ pure a = replaceVec_ a++ (<*>) = apVec ($)++instance SingI n => Distributive (Vec n) where+ distribute :: Functor f => f (Vec n a) -> Vec n (f a)+ distribute = distributeRep++instance SingI n => Representable (Vec n) where+ type Rep (Vec n) = Fin n++ tabulate :: (Fin n -> a) -> Vec n a+ tabulate = genVec_++ index :: Vec n a -> Fin n -> a+ index = flip indexVec++instance SingI n => Monad (Vec n) where+ (>>=) :: Vec n a -> (a -> Vec n b) -> Vec n b+ (>>=) = bindRep++type instance Element (Vec n a) = a++genVec_ :: SingI n => (Fin n -> a) -> Vec n a+genVec_ = genVec sing++genVec :: SPeano n -> (Fin n -> a) -> Vec n a+genVec SZ _ = EmptyVec+genVec (SS n) f = f FZ :* genVec n (f . FS)++indexVec :: Fin n -> Vec n a -> a+indexVec FZ (a :* _) = a+indexVec (FS n) (_ :* vec) = indexVec n vec++singletonVec :: a -> Vec N1 a+singletonVec a = ConsVec a EmptyVec++replaceVec :: Sing n -> a -> Vec n a+replaceVec SZ _ = EmptyVec+replaceVec (SS n) a = a :* replaceVec n a++imapVec :: forall n a b. (Fin n -> a -> b) -> Vec n a -> Vec n b+imapVec _ EmptyVec = EmptyVec+imapVec f (a :* as) = f FZ a :* imapVec (\fin vec -> f (FS fin) vec) as++replaceVec_ :: SingI n => a -> Vec n a+replaceVec_ = replaceVec sing++apVec :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c+apVec _ EmptyVec _ = EmptyVec+apVec f (a :* as) (b :* bs) = f a b :* apVec f as bs++onHeadVec :: (a -> a) -> Vec ('S n) a -> Vec ('S n) a+onHeadVec f (a :* as) = f a :* as++dropVec :: Sing m -> Vec (m + n) a -> Vec n a+dropVec SZ vec = vec+dropVec (SS n) (_ :* vec) = dropVec n vec++takeVec :: IFin n m -> Vec n a -> Vec m a+takeVec IFZ _ = EmptyVec+takeVec (IFS n) (a :* vec) = a :* takeVec n vec++updateAtVec :: Fin n -> (a -> a) -> Vec n a -> Vec n a+updateAtVec FZ f (a :* vec) = f a :* vec+updateAtVec (FS n) f (a :* vec) = a :* updateAtVec n f vec++setAtVec :: Fin n -> a -> Vec n a -> Vec n a+setAtVec fin a = updateAtVec fin (const a)++------------+-- Matrix --+------------++type family MatrixTF (ns :: [Peano]) (a :: Type) :: Type where+ MatrixTF '[] a = a+ MatrixTF (n ': ns) a = Vec n (MatrixTF ns a)++newtype Matrix ns a = Matrix+ { unMatrix :: MatrixTF ns a+ }+ deriving anyclass (MonoFoldable)++type instance Element (Matrix ns a) = a++---------------------------------+-- Defunctionalization Symbols --+---------------------------------++type MatrixTFSym2 (ns :: [Peano]) (t :: Type) = (MatrixTF ns t :: Type)++data MatrixTFSym1 (ns :: [Peano]) (z :: TyFun Type Type)+ = forall (arg :: Type). SameKind (Apply (MatrixTFSym1 ns) arg) (MatrixTFSym2 ns arg) => MatrixTFSym1KindInference++type instance Apply (MatrixTFSym1 l1) l2 = MatrixTF l1 l2++type role MatrixTFSym0 phantom++data MatrixTFSym0 (l :: TyFun [Peano] (Type ~> Type))+ = forall (arg :: [Peano]). SameKind (Apply MatrixTFSym0 arg) (MatrixTFSym1 arg) => MatrixTFSym0KindInference++type instance Apply MatrixTFSym0 l = MatrixTFSym1 l++type role MatrixTFSym1 phantom phantom++----------------------+-- Matrix Functions --+----------------------++eqSingMatrix :: forall (peanos :: [Peano]) (a :: Type). Eq a => Sing peanos -> Matrix peanos a -> Matrix peanos a -> Bool+eqSingMatrix = compareSingMatrix (==) True (&&)++ordSingMatrix :: forall (peanos :: [Peano]) (a :: Type). Ord a => Sing peanos -> Matrix peanos a -> Matrix peanos a -> Ordering+ordSingMatrix = compareSingMatrix compare EQ f+ where+ f :: Ordering -> Ordering -> Ordering+ f EQ o = o+ f o _ = o++compareSingMatrix ::+ forall (peanos :: [Peano]) (a :: Type) (c :: Type)+ . (a -> a -> c)+ -> c+ -> (c -> c -> c)+ -> Sing peanos+ -> Matrix peanos a+ -> Matrix peanos a+ -> c+compareSingMatrix f _ _ SNil (Matrix a) (Matrix b) = f a b+compareSingMatrix _ empt _ (SCons SZ _) (Matrix EmptyVec) (Matrix EmptyVec) = empt+compareSingMatrix f empt combine (SCons (SS peanoSingle) moreN) (Matrix (a :* moreA)) (Matrix (b :* moreB)) =+ combine+ (compareSingMatrix f empt combine moreN (Matrix a) (Matrix b))+ (compareSingMatrix f empt combine (SCons peanoSingle moreN) (Matrix moreA) (Matrix moreB))++fmapSingMatrix :: forall (peanos :: [Peano]) (a :: Type) (b ::Type). Sing peanos -> (a -> b) -> Matrix peanos a -> Matrix peanos b+fmapSingMatrix SNil f (Matrix a) = Matrix $ f a+fmapSingMatrix (SCons SZ _) _ (Matrix EmptyVec) = Matrix EmptyVec+fmapSingMatrix (SCons (SS peanoSingle) moreN) f (Matrix (a :* moreA)) =+ let matA = fmapSingMatrix moreN f (Matrix a)+ matB = fmapSingMatrix (SCons peanoSingle moreN) f (Matrix moreA)+ in consMatrix matA matB++consMatrix :: Matrix ns a -> Matrix (n ': ns) a -> Matrix ('S n ': ns) a+consMatrix (Matrix a) (Matrix as) = Matrix $ ConsVec a as++toListMatrix ::+ forall (peanos :: [Peano]) (a :: Type).+ Sing peanos+ -> Matrix peanos a+ -> [a]+toListMatrix SNil (Matrix a) = [a]+toListMatrix (SCons SZ _) (Matrix EmptyVec) = []+toListMatrix (SCons (SS peanoSingle) moreN) (Matrix (a :* moreA)) =+ toListMatrix moreN (Matrix a) <> toListMatrix (SCons peanoSingle moreN) (Matrix moreA)++genMatrix ::+ forall (ns :: [Peano]) (a :: Type).+ Sing ns+ -> (HList Fin ns -> a)+ -> Matrix ns a+genMatrix SNil f = Matrix $ f EmptyHList+genMatrix (SCons (n :: SPeano foo) (ns' :: Sing oaoa)) f =+ Matrix $ (genVec n $ (gagaga :: Fin foo -> MatrixTF oaoa a) :: Vec foo (MatrixTF oaoa a))+ where+ gagaga :: Fin foo -> MatrixTF oaoa a+ gagaga faaa = unMatrix $ (genMatrix ns' $ byebye faaa :: Matrix oaoa a)++ byebye :: Fin foo -> HList Fin oaoa -> a+ byebye faaa = f . ConsHList faaa++genMatrix_ :: SingI ns => (HList Fin ns -> a) -> Matrix ns a+genMatrix_ = genMatrix sing++indexMatrix :: HList Fin ns -> Matrix ns a -> a+indexMatrix EmptyHList (Matrix a) = a+indexMatrix (i :< is) (Matrix vec) = indexMatrix is $ Matrix (indexVec i vec)++imapMatrix :: forall (ns :: [Peano]) a b. Sing ns -> (HList Fin ns -> a -> b) -> Matrix ns a -> Matrix ns b+imapMatrix SNil f (Matrix a) = Matrix (f EmptyHList a)+imapMatrix (SCons _ ns) f matrix =+ onMatrixTF+ (imapVec (\fin -> onMatrix (imapMatrix ns (\hlist -> f (ConsHList fin hlist)))))+ matrix++imapMatrix_ :: SingI ns => (HList Fin ns -> a -> b) -> Matrix ns a -> Matrix ns b+imapMatrix_ = imapMatrix sing++onMatrixTF :: (MatrixTF ns a -> MatrixTF ms b) -> Matrix ns a -> Matrix ms b+onMatrixTF f (Matrix mat) = Matrix $ f mat++onMatrix :: (Matrix ns a -> Matrix ms b) -> MatrixTF ns a -> MatrixTF ms b+onMatrix f = unMatrix . f . Matrix++updateAtMatrix :: HList Fin ns -> (a -> a) -> Matrix ns a -> Matrix ns a+updateAtMatrix EmptyHList _ mat = mat+updateAtMatrix (n :< ns) f mat =+ onMatrixTF (updateAtVec n (onMatrix (updateAtMatrix ns f))) mat++setAtMatrix :: HList Fin ns -> a -> Matrix ns a -> Matrix ns a+setAtMatrix fins a = updateAtMatrix fins (const a)++----------------------+-- Matrix Instances --+----------------------++deriving instance (Eq (MatrixTF ns a)) => Eq (Matrix ns a)++deriving instance (Ord (MatrixTF ns a)) => Ord (Matrix ns a)++deriving instance (Show (MatrixTF ns a)) => Show (Matrix ns a)++instance SingI ns => Functor (Matrix ns) where+ fmap :: (a -> b) -> Matrix ns a -> Matrix ns b+ fmap = fmapSingMatrix (sing @_ @ns)++instance SingI ns => Data.Foldable.Foldable (Matrix ns) where+ foldr :: (a -> b -> b) -> b -> Matrix ns a -> b+ foldr comb b = Data.Foldable.foldr comb b . toListMatrix (sing @_ @ns)++ toList :: Matrix ns a -> [a]+ toList = toListMatrix (sing @_ @ns)++instance SingI ns => Distributive (Matrix ns) where+ distribute :: Functor f => f (Matrix ns a) -> Matrix ns (f a)+ distribute = distributeRep++instance SingI ns => Representable (Matrix ns) where+ type Rep (Matrix ns) = HList Fin ns++ tabulate :: (HList Fin ns -> a) -> Matrix ns a+ tabulate = genMatrix_++ index :: Matrix ns a -> HList Fin ns -> a+ index = flip indexMatrix++instance Num a => Num (Matrix '[] a) where+ Matrix a + Matrix b = Matrix (a + b)++ Matrix a * Matrix b = Matrix (a * b)++ Matrix a - Matrix b = Matrix (a - b)++ abs (Matrix a) = Matrix (abs a)++ signum (Matrix a) = Matrix (signum a)++ fromInteger :: Integer -> Matrix '[] a+ fromInteger = Matrix . fromInteger++instance SingI ns => Applicative (Matrix ns) where+ pure :: a -> Matrix ns a+ pure = pureRep++ (<*>) :: Matrix ns (a -> b) -> Matrix ns a -> Matrix ns b+ (<*>) = apRep++instance SingI ns => Monad (Matrix ns) where+ (>>=) :: Matrix ns a -> (a -> Matrix ns b) -> Matrix ns b+ (>>=) = bindRep
− src/Termonad/FocusList.hs
@@ -1,830 +0,0 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}--module Termonad.FocusList where--import Termonad.Prelude--import Control.Lens-import qualified Data.Foldable as Foldable-import Test.QuickCheck-import Text.Show (Show(showsPrec), ShowS, showParen, showString)---- $setup--- >>> :set -XFlexibleContexts--- >>> :set -XScopedTypeVariables--data Focus = Focus {-# UNPACK #-} !Int | NoFocus deriving (Eq, Generic, Read, Show)---- | 'NoFocus' is always less than 'Focus'.------ prop> NoFocus < Focus a-instance Ord Focus where- compare :: Focus -> Focus -> Ordering- compare NoFocus NoFocus = EQ- compare NoFocus (Focus _) = LT- compare (Focus _) NoFocus = GT- compare (Focus a) (Focus b) = compare a b--instance CoArbitrary Focus--foldFocus :: b -> (Int -> b) -> Focus -> b-foldFocus b _ NoFocus = b-foldFocus _ f (Focus i) = f i--_Focus :: Prism' Focus Int-_Focus = prism' Focus (foldFocus Nothing Just)--_NoFocus :: Prism' Focus ()-_NoFocus = prism' (const NoFocus) (foldFocus (Just ()) (const Nothing))--hasFocus :: Focus -> Bool-hasFocus NoFocus = False-hasFocus (Focus _) = True--unsafeGetFocus :: Focus -> Int-unsafeGetFocus NoFocus = error "unsafeGetFocus: NoFocus"-unsafeGetFocus (Focus i) = i---- TODO: Probably be better--- implemented as an Order statistic tree--- (https://en.wikipedia.org/wiki/Order_statistic_tree).-data FocusList a = FocusList- { focusListFocus :: !Focus- , focusListLen :: {-# UNPACK #-} !Int- , focusList :: !(IntMap a)- } deriving (Eq, Generic)--$(makeLensesFor- [ ("focusListFocus", "lensFocusListFocus")- , ("focusListLen", "lensFocusListLen")- , ("focusList", "lensFocusList")- ]- ''FocusList- )--instance Functor FocusList where- fmap :: (a -> b) -> FocusList a -> FocusList b- fmap f (FocusList focus len intmap) = FocusList focus len (fmap f intmap)--instance Foldable FocusList where- foldr f b (FocusList _ _ intmap) = Foldable.foldr f b intmap--instance Traversable FocusList where- traverse :: Applicative f => (a -> f b) -> FocusList a -> f (FocusList b)- traverse f (FocusList focus len intmap) = FocusList focus len <$> traverse f intmap--type instance Element (FocusList a) = a--instance MonoFunctor (FocusList a)--instance MonoFoldable (FocusList a)--instance MonoTraversable (FocusList a)--instance Arbitrary1 FocusList where- liftArbitrary :: Gen a -> Gen (FocusList a)- liftArbitrary genA = do- arbList <- liftArbitrary genA- case arbList of- [] -> pure emptyFL- (_:_) -> do- let listLen = length arbList- len <- choose (0, listLen - 1)- pure $ unsafeFLFromList (Focus len) arbList--instance Arbitrary a => Arbitrary (FocusList a) where- arbitrary = arbitrary1--instance CoArbitrary a => CoArbitrary (FocusList a)--debugFL :: Show a => FocusList a -> String-debugFL FocusList{..} =- showString "FocusList {" .- showString "focusListFocus = " .- showsPrec 0 focusListFocus .- showString ", " .- showString "focusListLen = " .- showsPrec 0 focusListLen .- showString ", " .- showString "focusList = " .- showsPrec 0 focusList $- showString "}" ""--instance Show a => Show (FocusList a) where- showsPrec :: Int -> FocusList a -> ShowS- showsPrec d FocusList{..} =- let list = fmap snd $ sortOn fst $ mapToList focusList- in- showParen (d > 10) $- showString "FocusList " .- showsPrec 11 focusListFocus .- showString " " .- showsPrec 11 list--lensFocusListAt :: Int -> Lens' (FocusList a) (Maybe a)-lensFocusListAt i = lensFocusList . at i---- | This is an invariant that the 'FocusList' must always protect.-invariantFL :: FocusList a -> Bool-invariantFL fl =- invariantFocusNotNeg &&- invariantFocusInMap &&- invariantFocusIfLenGT0 &&- invariantLenIsCorrect &&- invariantNoSkippedNumsInMap- where- -- This makes sure that the 'Focus' in a 'FocusList' can never be negative.- invariantFocusNotNeg :: Bool- invariantFocusNotNeg =- case fl ^. lensFocusListFocus of- NoFocus -> True- Focus i -> i >= 0-- -- | This makes sure that if there is a 'Focus', then it actually exists in- -- the 'FocusList'.- invariantFocusInMap :: Bool- invariantFocusInMap =- case fl ^. lensFocusListFocus of- NoFocus -> length (fl ^. lensFocusList) == 0- Focus i ->- case lookup i (fl ^. lensFocusList) of- Nothing -> False- Just _ -> True-- -- | This makes sure that there needs to be a 'Focus' if the length of the- -- 'FocusList' is greater than 0.- invariantFocusIfLenGT0 :: Bool- invariantFocusIfLenGT0 =- let len = fl ^. lensFocusListLen- focus = fl ^. lensFocusListFocus- in- case focus of- Focus _ -> len /= 0- NoFocus -> len == 0-- -- | Make sure that the length of the 'FocusList' is actually the number of- -- elements in the inner 'IntMap'.- invariantLenIsCorrect :: Bool- invariantLenIsCorrect =- let len = fl ^. lensFocusListLen- intmap = fl ^. lensFocusList- in len == length intmap-- -- | Make sure that there are no numbers that have been skipped in the- -- inner 'IntMap'.- invariantNoSkippedNumsInMap :: Bool- invariantNoSkippedNumsInMap =- let len = fl ^. lensFocusListLen- intmap = fl ^. lensFocusList- indexes = sort $ fmap fst $ mapToList intmap- in indexes == [0..(len - 1)]----- | Unsafely create a 'FocusList'. This does not check that the focus--- actually exists in the list.------ >>> let fl = unsafeFLFromList (Focus 1) [0..2]--- >>> debugFL fl--- "FocusList {focusListFocus = Focus 1, focusListLen = 3, focusList = fromList [(0,0),(1,1),(2,2)]}"------ >>> let fl = unsafeFLFromList NoFocus []--- >>> debugFL fl--- "FocusList {focusListFocus = NoFocus, focusListLen = 0, focusList = fromList []}"-unsafeFLFromList :: Focus -> [a] -> FocusList a-unsafeFLFromList focus list =- let len = length list- in- FocusList- { focusListFocus = focus- , focusListLen = len- , focusList = mapFromList $ zip [0..] list- }--focusItemGetter :: Getter (FocusList a) (Maybe a)-focusItemGetter = to getFLFocusItem---- | Safely create a 'FocusList' from a list.------ >>> flFromList (Focus 1) ["cat","dog","goat"]--- Just (FocusList (Focus 1) ["cat","dog","goat"])------ >>> flFromList NoFocus []--- Just (FocusList NoFocus [])------ If the 'Focus' is out of range for the list, then 'Nothing' will be returned.------ >>> flFromList (Focus (-1)) ["cat","dog","goat"]--- Nothing------ >>> flFromList (Focus 3) ["cat","dog","goat"]--- Nothing------ >>> flFromList NoFocus ["cat","dog","goat"]--- Nothing-flFromList :: Focus -> [a] -> Maybe (FocusList a)-flFromList NoFocus [] = Just emptyFL-flFromList _ [] = Nothing-flFromList NoFocus (_:_) = Nothing-flFromList (Focus i) list =- let len = length list- in- if i < 0 || i >= len- then Nothing- else- Just $- FocusList- { focusListFocus = Focus i- , focusListLen = len- , focusList = mapFromList $ zip [0..] list- }---- | Create a 'FocusList' with a single element.------ >>> singletonFL "hello"--- FocusList (Focus 0) ["hello"]-singletonFL :: a -> FocusList a-singletonFL a =- FocusList- { focusListFocus = Focus 0- , focusListLen = 1- , focusList = singletonMap 0 a- }---- | Create an empty 'FocusList' without a 'Focus'.------ >>> emptyFL--- FocusList NoFocus []-emptyFL :: FocusList a-emptyFL =- FocusList- { focusListFocus = NoFocus- , focusListLen = 0- , focusList = mempty- }---- | Return 'True' if the 'FocusList' is empty.------ >>> isEmptyFL emptyFL--- True------ >>> isEmptyFL $ singletonFL "hello"--- False------ Any 'FocusList' with a 'Focus' should never be empty.-isEmptyFL :: FocusList a -> Bool-isEmptyFL fl = fl ^. lensFocusListLen == 0---- | Append a value to the end of a 'FocusList'.------ This can be thought of as a \"snoc\" operation.------ >>> appendFL emptyFL "hello"--- FocusList (Focus 0) ["hello"]------ >>> appendFL (singletonFL "hello") "bye"--- FocusList (Focus 0) ["hello","bye"]------ Appending a value to an empty 'FocusList' is the same as using 'singletonFL'.------ prop> appendFL emptyFL a == singletonFL a-appendFL :: FocusList a -> a -> FocusList a-appendFL fl a =- if isEmptyFL fl- then singletonFL a- else unsafeInsertNewFL (fl ^. lensFocusListLen) a fl---- | A combination of 'appendFL' and 'setFocusFL'.------ >>> let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]--- >>> appendSetFocusFL fl "pie"--- FocusList (Focus 3) ["hello","bye","tree","pie"]------ prop> (appendSetFocusFL fl a) ^. lensFocusListFocus /= fl ^. lensFocusListFocus-appendSetFocusFL :: FocusList a -> a -> FocusList a-appendSetFocusFL fl a =- let oldLen = fl ^. lensFocusListLen- in- case setFocusFL oldLen (appendFL fl a) of- Nothing -> error "Internal error with setting the focus. This should never happen."- Just newFL -> newFL---- | Prepend a value to a 'FocusList'.------ This can be thought of as a \"cons\" operation.------ >>> prependFL "hello" emptyFL--- FocusList (Focus 0) ["hello"]------ The focus will be updated when prepending:------ >>> prependFL "bye" (singletonFL "hello")--- FocusList (Focus 1) ["bye","hello"]------ Prepending to a 'FocusList' will always update the 'Focus':------ prop> (fl ^. lensFocusListFocus) < (prependFL a fl ^. lensFocusListFocus)-prependFL :: a -> FocusList a -> FocusList a-prependFL a fl =- if isEmptyFL fl- then singletonFL a- else unsafeInsertNewFL 0 a $ unsafeShiftUpFrom 0 fl---- | Unsafely get the 'Focus' from a 'FocusList'. If the 'Focus' is--- 'NoFocus', this function returns 'error'.-unsafeGetFLFocus :: FocusList a -> Int-unsafeGetFLFocus fl =- let focus = fl ^. lensFocusListFocus- in- case focus of- NoFocus -> error "unsafeGetFLFocus: the focus list doesn't have a focus"- Focus i -> i---- | Unsafely get the value of the 'Focus' from a 'FocusList'. If the 'Focus' is--- 'NoFocus', this function returns 'error'.-unsafeGetFLFocusItem :: FocusList a -> a-unsafeGetFLFocusItem fl =- let focus = fl ^. lensFocusListFocus- in- case focus of- NoFocus -> error "unsafeGetFLFocusItem: the focus list doesn't have a focus"- Focus i ->- let intmap = fl ^. lensFocusList- in- case lookup i intmap of- Nothing ->- error $- "unsafeGetFLFocusItem: internal error, i (" <>- show i <>- ") doesnt exist in intmap"- Just a -> a--getFLFocusItem :: FocusList a -> Maybe a-getFLFocusItem fl =- let focus = fl ^. lensFocusListFocus- in- case focus of- NoFocus -> Nothing- Focus i ->- let intmap = fl ^. lensFocusList- in- case lookup i intmap of- Nothing ->- error $- "getFLFocusItem: internal error, i (" <>- show i <>- ") doesnt exist in intmap"- Just a -> Just a---- | Unsafely insert a new @a@ in a 'FocusList'. This sets the 'Int' value to--- @a@. The length of the 'FocusList' will be increased by 1. The--- 'FocusList's 'Focus' is not changed.------ If there is some value in the 'FocusList' already at the 'Int', then it will--- be overwritten. Also, the 'Int' is not checked to make sure it is above 0.------ This function is meant to be used after 'unsafeShiftUpFrom'.------ >>> let fl = unsafeShiftUpFrom 2 $ unsafeFLFromList (Focus 1) [0,1,200]--- >>> debugFL $ unsafeInsertNewFL 2 100 fl--- "FocusList {focusListFocus = Focus 1, focusListLen = 4, focusList = fromList [(0,0),(1,1),(2,100),(3,200)]}"------ >>> let fl = unsafeFLFromList NoFocus []--- >>> debugFL $ unsafeInsertNewFL 0 100 fl--- "FocusList {focusListFocus = NoFocus, focusListLen = 1, focusList = fromList [(0,100)]}"-unsafeInsertNewFL :: Int -> a -> FocusList a -> FocusList a-unsafeInsertNewFL i a fl =- fl &- lensFocusListLen +~ 1 &- lensFocusListAt i ?~ a---- | This unsafely shifts all values up in a 'FocusList' starting at a given--- index. It also updates the 'Focus' of the 'FocusList' if it has been--- shifted. This does not change the length of the 'FocusList'.------ It does not check that the 'Int' is greater than 0. It also does not check--- that there is a 'Focus'.------ ==== __EXAMPLES__------ >>> let fl = unsafeShiftUpFrom 2 $ unsafeFLFromList (Focus 1) [0,1,200]--- >>> debugFL fl--- "FocusList {focusListFocus = Focus 1, focusListLen = 3, focusList = fromList [(0,0),(1,1),(3,200)]}"------ >>> let fl = unsafeShiftUpFrom 1 $ unsafeFLFromList (Focus 1) [0,1,200]--- >>> debugFL fl--- "FocusList {focusListFocus = Focus 2, focusListLen = 3, focusList = fromList [(0,0),(2,1),(3,200)]}"------ >>> let fl = unsafeShiftUpFrom 0 $ unsafeFLFromList (Focus 1) [0,1,200]--- >>> debugFL fl--- "FocusList {focusListFocus = Focus 2, focusListLen = 3, focusList = fromList [(1,0),(2,1),(3,200)]}"------ >>> let fl = unsafeShiftUpFrom 0 $ unsafeFLFromList (Focus 1) [0,1,200]--- >>> debugFL fl--- "FocusList {focusListFocus = Focus 2, focusListLen = 3, focusList = fromList [(1,0),(2,1),(3,200)]}"-unsafeShiftUpFrom :: forall a. Int -> FocusList a -> FocusList a-unsafeShiftUpFrom i fl =- let intMap = fl ^. lensFocusList- lastElemIdx = (fl ^. lensFocusListLen) - 1- newIntMap = go i lastElemIdx intMap- oldFocus = unsafeGetFLFocus fl- newFocus = if i > oldFocus then oldFocus else oldFocus + 1- in- fl &- lensFocusList .~ newIntMap &- lensFocusListFocus .~ Focus newFocus- where- go :: Int -> Int -> IntMap a -> IntMap a- go idxToInsert idxToShiftUp intMap- | idxToInsert <= idxToShiftUp =- let val = unsafeLookup idxToShiftUp intMap- newMap =- insertMap (idxToShiftUp + 1) val (deleteMap idxToShiftUp intMap)- in go idxToInsert (idxToShiftUp - 1) newMap- | otherwise = intMap---- | This is an unsafe lookup function. This assumes that the 'Int' exists in--- the 'IntMap'.-unsafeLookup :: Int -> IntMap a -> a-unsafeLookup i intmap =- case lookup i intmap of- Nothing -> error $ "unsafeLookup: key " <> show i <> " not found in intmap"- Just a -> a--lookupFL :: Int -> FocusList a -> Maybe a-lookupFL i fl = lookup i (fl ^. lensFocusList)---- | Insert a new value into the 'FocusList'. The 'Focus' of the list is--- changed appropriately.------ >>> insertFL 0 "hello" emptyFL--- Just (FocusList (Focus 0) ["hello"])------ >>> insertFL 0 "hello" (singletonFL "bye")--- Just (FocusList (Focus 1) ["hello","bye"])------ >>> insertFL 1 "hello" (singletonFL "bye")--- Just (FocusList (Focus 0) ["bye","hello"])------ This returns 'Nothing' if the index at which to insert the new value is--- either less than 0 or greater than the length of the list.------ >>> insertFL 100 "hello" emptyFL--- Nothing------ >>> insertFL 100 "bye" (singletonFL "hello")--- Nothing------ >>> insertFL (-1) "bye" (singletonFL "hello")--- Nothing-insertFL- :: Int -- ^ The index at which to insert the value.- -> a- -> FocusList a- -> Maybe (FocusList a)-insertFL i a fl- | i < 0 || i > (fl ^. lensFocusListLen) =- -- Return Nothing if the insertion position is out of bounds.- Nothing- | i == 0 && isEmptyFL fl =- -- Return a 'FocusList' with one element if the insertion position is 0- -- and the 'FocusList' is empty.- Just $ singletonFL a- | otherwise =- -- Shift all existing values up one and insert the new- -- value in the opened place.- let shiftedUpFL = unsafeShiftUpFrom i fl- in Just $ unsafeInsertNewFL i a shiftedUpFL---- | Unsafely remove a value from a 'FocusList'. It effectively leaves a hole--- inside the 'FocusList'. It updates the length of the 'FocusList'.------ This function does not check that a value actually exists in the--- 'FocusList'. It also does not update the 'Focus'.------ This function does update the length of the 'FocusList'.------ >>> debugFL $ unsafeRemove 1 $ unsafeFLFromList (Focus 0) [0..2]--- "FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,0),(2,2)]}"------ >>> debugFL $ unsafeRemove 0 $ unsafeFLFromList (Focus 0) [0..2]--- "FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(1,1),(2,2)]}"------ Trying to remove the last element is completely safe (unless, of course, it--- is the 'Focus'):------ >>> debugFL $ unsafeRemove 2 $ unsafeFLFromList (Focus 2) [0..2]--- "FocusList {focusListFocus = Focus 2, focusListLen = 2, focusList = fromList [(0,0),(1,1)]}"------ If this function is passed an empty 'FocusList', it will make the length -1.------ >>> debugFL $ unsafeRemove 0 emptyFL--- "FocusList {focusListFocus = NoFocus, focusListLen = -1, focusList = fromList []}"-unsafeRemove- :: Int- -> FocusList a- -> FocusList a-unsafeRemove i fl =- fl &- lensFocusListLen -~ 1 &- lensFocusListAt i .~ Nothing---- | This shifts all the values down in a 'FocusList' starting at a given--- index. It does not change the 'Focus' of the 'FocusList'. It does not change the--- length of the 'FocusList'.------ It does not check that shifting elements down will not overwrite other elements.--- This function is meant to be called after 'unsafeRemove'.------ >>> let fl = unsafeRemove 1 $ unsafeFLFromList (Focus 0) [0..2]--- >>> debugFL $ unsafeShiftDownFrom 1 fl--- "FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,0),(1,2)]}"------ >>> let fl = unsafeRemove 0 $ unsafeFLFromList (Focus 0) [0..2]--- >>> debugFL $ unsafeShiftDownFrom 0 fl--- "FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,1),(1,2)]}"------ Trying to shift down from the last element after it has been removed is a no-op:------ >>> let fl = unsafeRemove 2 $ unsafeFLFromList (Focus 0) [0..2]--- >>> debugFL $ unsafeShiftDownFrom 2 fl--- "FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,0),(1,1)]}"-unsafeShiftDownFrom :: forall a. Int -> FocusList a -> FocusList a-unsafeShiftDownFrom i fl =- let intMap = fl ^. lensFocusList- len = fl ^. lensFocusListLen- newIntMap = go (i + 1) len intMap- in fl & lensFocusList .~ newIntMap- where- go :: Int -> Int -> IntMap a -> IntMap a- go idxToShiftDown len intMap- | idxToShiftDown < len + 1 =- let val = unsafeLookup idxToShiftDown intMap- newMap =- insertMap (idxToShiftDown - 1) val (deleteMap idxToShiftDown intMap)- in go (idxToShiftDown + 1) len newMap- | otherwise = intMap---- | Remove an element from a 'FocusList'.------ If the element to remove is not the 'Focus', then update the 'Focus'--- accordingly.------ For example, if the 'Focus' is on index 1, and we have removed index 2, then--- the focus is not affected, so it is not changed.------ >>> let focusList = unsafeFLFromList (Focus 1) ["cat","goat","dog","hello"]--- >>> removeFL 2 focusList--- Just (FocusList (Focus 1) ["cat","goat","hello"])------ If the 'Focus' is on index 2 and we have removed index 1, then the 'Focus'--- will be moved back one element to set to index 1.------ >>> let focusList = unsafeFLFromList (Focus 2) ["cat","goat","dog","hello"]--- >>> removeFL 1 focusList--- Just (FocusList (Focus 1) ["cat","dog","hello"])------ If we remove the 'Focus', then the next item is set to have the 'Focus'.------ >>> let focusList = unsafeFLFromList (Focus 0) ["cat","goat","dog","hello"]--- >>> removeFL 0 focusList--- Just (FocusList (Focus 0) ["goat","dog","hello"])------ If the element to remove is the only element in the list, then the 'Focus'--- will be set to 'NoFocus'.------ >>> let focusList = unsafeFLFromList (Focus 0) ["hello"]--- >>> removeFL 0 focusList--- Just (FocusList NoFocus [])------ If the 'Int' for the index to remove is either less than 0 or greater then--- the length of the list, then 'Nothing' is returned.------ >>> let focusList = unsafeFLFromList (Focus 0) ["hello"]--- >>> removeFL (-1) focusList--- Nothing------ >>> let focusList = unsafeFLFromList (Focus 1) ["hello","bye","cat"]--- >>> removeFL 3 focusList--- Nothing------ If the 'FocusList' passed in is 'Empty', then 'Nothing' is returned.------ >>> removeFL 0 emptyFL--- Nothing-removeFL- :: Int -- ^ Index of the element to remove from the 'FocusList'.- -> FocusList a -- ^ The 'FocusList' to remove an element from.- -> Maybe (FocusList a)-removeFL i fl- | i < 0 || i >= (fl ^. lensFocusListLen) || isEmptyFL fl =- -- Return Nothing if the removal position is out of bounds.- Nothing- | fl ^. lensFocusListLen == 1 =- -- Return an empty focus list if there is currently only one element- Just emptyFL- | otherwise =- let newFLWithHole = unsafeRemove i fl- newFL = unsafeShiftDownFrom i newFLWithHole- focus = unsafeGetFLFocus fl- in- if focus >= i && focus /= 0- then Just $ newFL & lensFocusListFocus . _Focus -~ 1- else Just newFL---- | Find the index of the first element in the 'FocusList'.------ >>> let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]--- >>> indexOfFL "hello" fl--- Just 0------ If more than one element exists, then return the index of the first one.------ >>> let Just fl = flFromList (Focus 1) ["dog", "cat", "cat"]--- >>> indexOfFL "cat" fl--- Just 1------ If the element doesn't exist, then return 'Nothing'------ >>> let Just fl = flFromList (Focus 1) ["foo", "bar", "baz"]--- >>> indexOfFL "hogehoge" fl--- Nothing-indexOfFL :: Eq a => a -> FocusList a -> Maybe Int-indexOfFL a fl =- let intmap = focusList fl- keyVals = sortOn fst $ mapToList intmap- maybeKeyVal = find (\(_, val) -> val == a) keyVals- in fmap fst maybeKeyVal---- | Delete an element from a 'FocusList'.------ >>> let Just fl = flFromList (Focus 0) ["hello", "bye", "tree"]--- >>> deleteFL "bye" fl--- FocusList (Focus 0) ["hello","tree"]------ The focus will be updated if an item before it is deleted.------ >>> let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]--- >>> deleteFL "hello" fl--- FocusList (Focus 0) ["bye","tree"]------ If there are multiple matching elements in the 'FocusList', remove them all.------ >>> let Just fl = flFromList (Focus 0) ["hello", "bye", "bye"]--- >>> deleteFL "bye" fl--- FocusList (Focus 0) ["hello"]------ If there are no matching elements, return the original 'FocusList'.------ >>> let Just fl = flFromList (Focus 2) ["hello", "good", "bye"]--- >>> deleteFL "frog" fl--- FocusList (Focus 2) ["hello","good","bye"]-deleteFL- :: forall a.- (Eq a)- => a- -> FocusList a- -> FocusList a-deleteFL item = go- where- go :: FocusList a -> FocusList a- go fl =- let maybeIndex = indexOfFL item fl- in- case maybeIndex of- Nothing -> fl- Just i ->- let maybeNewFL = removeFL i fl- in- case maybeNewFL of- Nothing -> fl- Just newFL -> go newFL---- | Set the 'Focus' for a 'FocusList'.------ This is just like 'updateFocusFL', but doesn't return the new focused item.------ prop> setFocusFL i fl == fmap snd (updateFocusFL i fl)-setFocusFL :: Int -> FocusList a -> Maybe (FocusList a)-setFocusFL i fl- -- Can't set a 'Focus' for an empty 'FocusList'.- | isEmptyFL fl = Nothing- | otherwise =- let len = fl ^. lensFocusListLen- in- if i < 0 || i >= len- then Nothing- else Just $ fl & lensFocusListFocus . _Focus .~ i---- | Update the 'Focus' for a 'FocusList' and get the new focused element.------ >>> updateFocusFL 1 =<< flFromList (Focus 2) ["hello","bye","dog","cat"]--- Just ("bye",FocusList (Focus 1) ["hello","bye","dog","cat"])------ If the 'FocusList' is empty, then return 'Nothing'.------ >>> updateFocusFL 1 emptyFL--- Nothing------ If the new focus is less than 0, or greater than or equal to the length of--- the 'FocusList', then return 'Nothing'.------ >>> updateFocusFL (-1) =<< flFromList (Focus 2) ["hello","bye","dog","cat"]--- Nothing------ >>> updateFocusFL 4 =<< flFromList (Focus 2) ["hello","bye","dog","cat"]--- Nothing-updateFocusFL :: Int -> FocusList a -> Maybe (a, FocusList a)-updateFocusFL i fl- | isEmptyFL fl = Nothing- | otherwise =- let len = fl ^. lensFocusListLen- in- if i < 0 || i >= len- then Nothing- else- let newFL = fl & lensFocusListFocus . _Focus .~ i- in Just (unsafeGetFLFocusItem newFL, newFL)---- | Find a value in a 'FocusList'. Similar to @Data.List.'Data.List.find'@.------ >>> let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]--- >>> findFL (\_ a -> a == "hello") fl--- Just (0,"hello")------ This will only find the first value.------ >>> let Just fl = flFromList (Focus 0) ["hello", "bye", "bye"]--- >>> findFL (\_ a -> a == "bye") fl--- Just (1,"bye")------ If no values match the comparison, this will return 'Nothing'.------ >>> let Just fl = flFromList (Focus 1) ["hello", "bye", "parrot"]--- >>> findFL (\_ a -> a == "ball") fl--- Nothing-findFL :: (Int -> a -> Bool) -> FocusList a -> Maybe (Int, a)-findFL f fl =- let intmap = fl ^. lensFocusList- vals = sortOn fst $ mapToList intmap- in find (\(i, a) -> f i a) vals----- | Move an existing item in a 'FocusList' to a new index.------ The 'Focus' gets updated appropriately when moving items.------ >>> let Just fl = flFromList (Focus 1) ["hello", "bye", "parrot"]--- >>> moveFromToFL 0 1 fl--- Just (FocusList (Focus 0) ["bye","hello","parrot"])------ The 'Focus' may not get updated if it is not involved.------ >>> let Just fl = flFromList (Focus 0) ["hello", "bye", "parrot"]--- >>> moveFromToFL 1 2 fl--- Just (FocusList (Focus 0) ["hello","parrot","bye"])------ If the element with the 'Focus' is moved, then the 'Focus' will be updated appropriately.------ >>> let Just fl = flFromList (Focus 2) ["hello", "bye", "parrot"]--- >>> moveFromToFL 2 0 fl--- Just (FocusList (Focus 0) ["parrot","hello","bye"])------ If the index of the item to move is out bounds, then 'Nothing' will be returned.------ >>> let Just fl = flFromList (Focus 2) ["hello", "bye", "parrot"]--- >>> moveFromToFL 3 0 fl--- Nothing------ If the new index is out of bounds, then 'Nothing' wil be returned.------ >>> let Just fl = flFromList (Focus 2) ["hello", "bye", "parrot"]--- >>> moveFromToFL 1 (-1) fl--- Nothing-moveFromToFL- :: Show a => Int -- ^ Index of the item to move.- -> Int -- ^ New index for the item.- -> FocusList a- -> Maybe (FocusList a)-moveFromToFL oldPos newPos fl- | oldPos < 0 || oldPos >= length fl = Nothing- | newPos < 0 || newPos >= length fl = Nothing- | otherwise =- let oldFocus = fl ^. lensFocusListFocus- in- case lookupFL oldPos fl of- Nothing -> error "moveFromToFL should have been able to lookup the item"- Just item ->- case removeFL oldPos fl of- Nothing -> error "moveFromToFL should have been able to remove old position"- Just flAfterRemove ->- case insertFL newPos item flAfterRemove of- Nothing -> error "moveFromToFL should have been able to reinsert the item"- Just flAfterInsert ->- if Focus oldPos == oldFocus- then- case setFocusFL newPos flAfterInsert of- Nothing -> error "moveFromToFL should have been able to reset the focus"- Just flWithUpdatedFocus -> Just flWithUpdatedFocus- else Just flAfterInsert
src/Termonad/Gtk.hs view
@@ -4,14 +4,14 @@ import Termonad.Prelude +import Data.GI.Base (ManagedPtr, withManagedPtr) import GHC.Stack (HasCallStack) import GI.Gdk ( GObject- , ManagedPtr , castTo ) import GI.Gio (ApplicationFlags)-import GI.Gtk (Application, applicationNew, builderGetObject)+import GI.Gtk (Application, IsWidget, Widget(Widget), applicationNew, builderGetObject, toWidget) import qualified GI.Gtk as Gtk @@ -31,9 +31,31 @@ " from builder, but couldn't convert to object!" Just obj -> pure obj -appNew :: (HasCallStack, MonadIO m) => Maybe Text -> [ApplicationFlags] -> m Application+-- | Unsafely creates a new 'Application'. This calls 'fail' if it cannot+-- create the 'Application' for some reason.+--+-- This can fail for different reasons, one of which being that application+-- name does not have a period in it.+appNew ::+ (HasCallStack, MonadIO m)+ => Maybe Text+ -- ^ The application name. Must have a period in it if specified. If passed+ -- as 'Nothing', then no application name will be used.+ -> [ApplicationFlags]+ -> m Application appNew appName appFlags = do maybeApp <- applicationNew appName appFlags case maybeApp of Nothing -> fail "Could not create application for some reason!" Just app -> pure app++-- | Tests to see if two GTK widgets point to the same thing. This should only+-- happen if they are actually the same thing.+widgetEq :: (MonadIO m, IsWidget a, IsWidget b) => a -> b -> m Bool+widgetEq a b = do+ Widget managedPtrA <- toWidget a+ Widget managedPtrB <- toWidget b+ liftIO $+ withManagedPtr managedPtrA $ \ptrA ->+ withManagedPtr managedPtrB $ \ptrB ->+ pure (ptrA == ptrB)
src/Termonad/Keys.hs view
@@ -6,6 +6,7 @@ import Control.Lens (imap) import GI.Gdk ( EventKey+ , pattern KEY_0 , pattern KEY_1 , pattern KEY_2 , pattern KEY_3@@ -71,6 +72,7 @@ , KEY_7 , KEY_8 , KEY_9+ , KEY_0 ] altNumKeys = imap
+ src/Termonad/Lenses.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE TemplateHaskell #-}++module Termonad.Lenses where++import Control.Lens (makeLensesFor, makePrisms)+import Termonad.Types++$(makeLensesFor+ [ ("term", "lensTerm")+ , ("pid", "lensPid")+ , ("unique", "lensUnique")+ ]+ ''TMTerm+ )++$(makeLensesFor+ [ ("tmNotebookTabTermContainer", "lensTMNotebookTabTermContainer")+ , ("tmNotebookTabTerm", "lensTMNotebookTabTerm")+ , ("tmNotebookTabLabel", "lensTMNotebookTabLabel")+ ]+ ''TMNotebookTab+ )++$(makeLensesFor+ [ ("tmNotebook", "lensTMNotebook")+ , ("tmNotebookTabs", "lensTMNotebookTabs")+ ]+ ''TMNotebook+ )++$(makeLensesFor+ [ ("tmStateApp", "lensTMStateApp")+ , ("tmStateAppWin", "lensTMStateAppWin")+ , ("tmStateNotebook", "lensTMStateNotebook")+ , ("tmStateFontDesc", "lensTMStateFontDesc")+ , ("tmStateConfig", "lensTMStateConfig")+ , ("tmStateUserReqExit", "lensTMStateUserReqExit")+ ]+ ''TMState'+ )++$(makePrisms ''FontSize)++$(makeLensesFor+ [ ("fontFamily", "lensFontFamily")+ , ("fontSize", "lensFontSize")+ ]+ ''FontConfig+ )++$(makeLensesFor+ [ ("fontConfig", "lensFontConfig")+ , ("showScrollbar", "lensShowScrollbar")+ , ("colourConfig", "lensColourConfig")+ , ("scrollbackLen", "lensScrollbackLen")+ , ("confirmExit", "lensConfirmExit")+ , ("wordCharExceptions", "lensWordCharExceptions")+ , ("showMenu", "lensShowMenu")+ , ("showTabBar", "lensShowTabBar")+ , ("cursorBlinkMode", "lensCursorBlinkMode")+ ]+ ''ConfigOptions+ )++$(makeLensesFor+ [ ("createTermHook", "lensCreateTermHook")+ ]+ ''ConfigHooks+ )++$(makeLensesFor+ [ ("options", "lensOptions")+ , ("hooks", "lensHooks")+ ]+ ''TMConfig+ )
src/Termonad/Prelude.hs view
@@ -1,8 +1,11 @@-{-# LANGUAGE NoImplicitPrelude #-}- module Termonad.Prelude ( module X+ , whenJust ) where +import Control.Lens as X ((&)) import ClassyPrelude as X import Data.Proxy as X++whenJust :: Monoid m => Maybe a -> (a -> m) -> m+whenJust = flip foldMap
src/Termonad/Term.hs view
@@ -5,7 +5,8 @@ import Termonad.Prelude import Control.Lens ((^.), (&), (.~), set, to)-import Data.Colour.SRGB (RGB(RGB), toSRGB)+import Data.Colour.SRGB (Colour, RGB(RGB), toSRGB)+import Data.FocusList (appendFL, deleteFL, getFocusItemFL) import GI.Gdk ( EventKey , RGBA@@ -48,8 +49,10 @@ , noAdjustment , notebookAppendPage , notebookDetachTab+ , notebookGetNPages , notebookPageNum , notebookSetCurrentPage+ , notebookSetShowTabs , notebookSetTabReorderable , onButtonClicked , onWidgetKeyPressEvent@@ -59,51 +62,63 @@ , widgetDestroy , widgetGrabFocus , widgetSetCanFocus+ , widgetSetFocusOnClick , widgetSetHalign , widgetSetHexpand , widgetShow+ , windowSetFocus , windowSetTransientFor ) import GI.Pango (EllipsizeMode(EllipsizeModeMiddle)) import GI.Vte- ( CursorBlinkMode(CursorBlinkModeOn)- , PtyFlags(PtyFlagsDefault)+ ( PtyFlags(PtyFlagsDefault) , Terminal , onTerminalChildExited , onTerminalWindowTitleChanged , terminalGetWindowTitle , terminalNew , terminalSetCursorBlinkMode- , terminalSetColorCursor , terminalSetFont , terminalSetScrollbackLines , terminalSpawnSync+ , terminalSetWordCharExceptions ) import System.FilePath ((</>)) import System.Directory (getSymbolicLinkTarget)+import System.Environment (lookupEnv) -import Termonad.Config (ShowScrollbar(..), TMConfig(cursorColor, scrollbackLen), lensShowScrollbar)-import Termonad.FocusList (appendFL, deleteFL, getFLFocusItem)-import Termonad.Types- ( TMNotebookTab- , TMState- , TMState'(TMState, tmStateConfig, tmStateFontDesc, tmStateNotebook)- , TMTerm- , createTMNotebookTab- , lensTerm+import Termonad.Lenses+ ( lensConfirmExit+ , lensOptions+ , lensShowScrollbar+ , lensShowTabBar , lensTMNotebookTabLabel- , lensTMNotebookTabs , lensTMNotebookTabTerm , lensTMNotebookTabTermContainer+ , lensTMNotebookTabs , lensTMStateApp , lensTMStateConfig , lensTMStateNotebook+ , lensTerm+ )+import Termonad.Types+ ( ConfigHooks(createTermHook)+ , ConfigOptions(scrollbackLen, wordCharExceptions, cursorBlinkMode)+ , ShowScrollbar(..)+ , ShowTabBar(..)+ , TMConfig(hooks, options)+ , TMNotebookTab+ , TMState+ , TMState'(TMState, tmStateAppWin, tmStateConfig, tmStateFontDesc, tmStateNotebook)+ , TMTerm+ , assertInvariantTMState+ , createTMNotebookTab , newTMTerm , pid , tmNotebook- , tmNotebookTabs , tmNotebookTabTerm , tmNotebookTabTermContainer+ , tmNotebookTabs ) focusTerm :: Int -> TMState -> IO ()@@ -118,11 +133,18 @@ termExitFocused mvarTMState = do tmState <- readMVar mvarTMState let maybeTab =- tmState ^. lensTMStateNotebook . lensTMNotebookTabs . to getFLFocusItem+ tmState ^. lensTMStateNotebook . lensTMNotebookTabs . to getFocusItemFL case maybeTab of Nothing -> pure ()- Just tab -> termExitWithConfirmation tab mvarTMState+ Just tab -> termClose tab mvarTMState +termClose :: TMNotebookTab -> TMState -> IO ()+termClose tab mvarTMState = do+ tmState <- readMVar mvarTMState+ let confirm = tmState ^. lensTMStateConfig . lensOptions . lensConfirmExit+ close = if confirm then termExitWithConfirmation else termExit+ close tab mvarTMState+ termExitWithConfirmation :: TMNotebookTab -> TMState -> IO () termExitWithConfirmation tab mvarTMState = do tmState <- readMVar mvarTMState@@ -185,7 +207,7 @@ relabelTab notebook label scrolledWin term' = do pageNum <- notebookPageNum notebook scrolledWin maybeTitle <- terminalGetWindowTitle term'- let title = fromMaybe "bash" maybeTitle+ let title = fromMaybe "shell" maybeTitle labelSetLabel label $ tshow (pageNum + 1) <> ". " <> title showScrollbarToPolicy :: ShowScrollbar -> PolicyType@@ -196,7 +218,7 @@ createScrolledWin :: TMState -> IO ScrolledWindow createScrolledWin mvarTMState = do tmState <- readMVar mvarTMState- let showScrollbarVal = tmState ^. lensTMStateConfig . lensShowScrollbar+ let showScrollbarVal = tmState ^. lensTMStateConfig . lensOptions . lensShowScrollbar vScrollbarPolicy = showScrollbarToPolicy showScrollbarVal scrolledWin <- scrolledWindowNew noAdjustment noAdjustment widgetShow scrolledWin@@ -219,17 +241,29 @@ containerAdd box label containerAdd box button widgetSetCanFocus button False+ widgetSetFocusOnClick button False widgetSetCanFocus label False+ widgetSetFocusOnClick label False widgetSetCanFocus box False+ widgetSetFocusOnClick box False widgetShow box widgetShow label widgetShow button pure (box, label, button) -getCursorColor :: TMConfig -> IO RGBA-getCursorColor tmConfig = do- let color = cursorColor tmConfig- RGB red green blue = toSRGB color+setShowTabs :: TMConfig -> Notebook -> IO ()+setShowTabs tmConfig note = do+ npages <- notebookGetNPages note+ let shouldShowTabs =+ case tmConfig ^. lensOptions . lensShowTabBar of+ ShowTabBarIfNeeded -> npages > 1+ ShowTabBarAlways -> True+ ShowTabBarNever -> False+ notebookSetShowTabs note shouldShowTabs++toRGBA :: Colour Double -> IO RGBA+toRGBA colour = do+ let RGB red green blue = toSRGB colour rgba <- newZeroRGBA setRGBARed rgba red setRGBAGreen rgba green@@ -259,24 +293,29 @@ createTerm :: (TMState -> EventKey -> IO Bool) -> TMState -> IO TMTerm createTerm handleKeyPress mvarTMState = do+ assertInvariantTMState mvarTMState scrolledWin <- createScrolledWin mvarTMState- TMState{tmStateFontDesc, tmStateConfig, tmStateNotebook=currNote} <- readMVar mvarTMState- let maybeCurrFocusedTabPid = pid . tmNotebookTabTerm <$> getFLFocusItem (tmNotebookTabs currNote)+ TMState{tmStateAppWin, tmStateFontDesc, tmStateConfig, tmStateNotebook=currNote} <-+ readMVar mvarTMState+ let maybeCurrFocusedTabPid = pid . tmNotebookTabTerm <$> getFocusItemFL (tmNotebookTabs currNote) maybeCurrDir <- maybe (pure Nothing) cwdOfPid maybeCurrFocusedTabPid vteTerm <- terminalNew terminalSetFont vteTerm (Just tmStateFontDesc)- terminalSetScrollbackLines vteTerm (fromIntegral (scrollbackLen tmStateConfig))- cursorColor <- getCursorColor tmStateConfig- terminalSetColorCursor vteTerm (Just cursorColor)- terminalSetCursorBlinkMode vteTerm CursorBlinkModeOn+ let curOpts = options tmStateConfig+ terminalSetWordCharExceptions vteTerm $ wordCharExceptions curOpts+ terminalSetScrollbackLines vteTerm (fromIntegral (scrollbackLen curOpts))+ terminalSetCursorBlinkMode vteTerm (cursorBlinkMode curOpts) widgetShow vteTerm- widgetGrabFocus $ vteTerm+ -- Should probably use GI.Vte.Functions.getUserShell, but contrary to its+ -- documentation it raises an exception rather wrap in Maybe.+ mShell <- lookupEnv "SHELL"+ let argv = fromMaybe ["/usr/bin/env", "bash"] (pure <$> mShell) terminalProcPid <- terminalSpawnSync vteTerm [PtyFlagsDefault] maybeCurrDir- ["/usr/bin/env", "bash"]+ argv Nothing ([SpawnFlagsDefault] :: [SpawnFlags]) Nothing@@ -287,21 +326,21 @@ let notebookTab = createTMNotebookTab tabLabel scrolledWin tmTerm void $ onButtonClicked tabCloseButton $- termExitWithConfirmation notebookTab mvarTMState- setCurrPageAction <-+ termClose notebookTab mvarTMState+ mvarReturnAction <- modifyMVar mvarTMState $ \tmState -> do let notebook = tmStateNotebook tmState note = tmNotebook notebook tabs = tmNotebookTabs notebook pageIndex <- notebookAppendPage note scrolledWin (Just tabLabelBox) notebookSetTabReorderable note scrolledWin True+ setShowTabs (tmState ^. lensTMStateConfig) note let newTabs = appendFL tabs notebookTab newTMState = tmState & lensTMStateNotebook . lensTMNotebookTabs .~ newTabs- setCurrPageAction = do- notebookSetCurrentPage note pageIndex- pure (newTMState, setCurrPageAction)- setCurrPageAction+ mvarReturnAction = notebookSetCurrentPage note pageIndex+ pure (newTMState, mvarReturnAction)+ mvarReturnAction relabelTab (tmNotebook currNote) tabLabel scrolledWin vteTerm void $ onTerminalWindowTitleChanged vteTerm $ do TMState{tmStateNotebook} <- readMVar mvarTMState@@ -310,4 +349,8 @@ void $ onWidgetKeyPressEvent vteTerm $ handleKeyPress mvarTMState void $ onWidgetKeyPressEvent scrolledWin $ handleKeyPress mvarTMState void $ onTerminalChildExited vteTerm $ \_ -> termExit notebookTab mvarTMState+ widgetGrabFocus vteTerm+ windowSetFocus tmStateAppWin (Just vteTerm)+ assertInvariantTMState mvarTMState+ createTermHook (hooks tmStateConfig) mvarTMState vteTerm pure tmTerm
src/Termonad/Types.hs view
@@ -1,30 +1,40 @@-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE StandaloneDeriving #-} module Termonad.Types where import Termonad.Prelude -import Control.Lens ((&), (.~), (^.), firstOf, makeLensesFor)+import Data.FocusList (FocusList, emptyFL, singletonFL, getFocusItemFL, lengthFL) import Data.Unique (Unique, hashUnique, newUnique) import GI.Gtk ( Application , ApplicationWindow+ , IsWidget , Label , Notebook , ScrolledWindow+ , Widget+ , notebookGetCurrentPage+ , notebookGetNthPage+ , notebookGetNPages ) import GI.Pango (FontDescription)-import GI.Vte (Terminal)+import GI.Vte (Terminal, CursorBlinkMode(CursorBlinkModeOn)) import Text.Pretty.Simple (pPrint) import Text.Show (Show(showsPrec), ShowS, showParen, showString) -import Termonad.Config (TMConfig)-import Termonad.FocusList (FocusList, emptyFL, focusItemGetter, singletonFL)+import Termonad.Gtk (widgetEq) +-- | A wrapper around a VTE 'Terminal'. This also stores the process ID of the+-- process running on this terminal, as well as a 'Unique' that can be used for+-- comparing terminals. data TMTerm = TMTerm { term :: !Terminal+ -- ^ The actual 'Terminal'. , pid :: !Int+ -- ^ The process ID of the process running in 'term'. , unique :: !Unique+ -- ^ A 'Unique' for comparing different 'TMTerm' for uniqueness. } instance Show TMTerm where@@ -42,18 +52,16 @@ showsPrec (d + 1) (hashUnique unique) . showString "}" -$(makeLensesFor- [ ("term", "lensTerm")- , ("pid", "lensPid")- , ("unique", "lensUnique")- ]- ''TMTerm- )-+-- | A container that holds everything in a given terminal window. The 'term'+-- in the 'TMTerm' is inside the 'tmNotebookTabTermContainer' 'ScrolledWindow'.+-- The notebook tab 'Label' is also available. data TMNotebookTab = TMNotebookTab { tmNotebookTabTermContainer :: !ScrolledWindow+ -- ^ The 'ScrolledWindow' holding the VTE 'Terminal'. , tmNotebookTabTerm :: !TMTerm+ -- ^ The 'Terminal' insidie the 'ScrolledWindow'. , tmNotebookTabLabel :: !Label+ -- ^ The 'Label' holding the title of the 'Terminal' in the 'Notebook' tab. } instance Show TMNotebookTab where@@ -71,17 +79,13 @@ showString "(GI.GTK.Label)" . showString "}" -$(makeLensesFor- [ ("tmNotebookTabTermContainer", "lensTMNotebookTabTermContainer")- , ("tmNotebookTabTerm", "lensTMNotebookTabTerm")- , ("tmNotebookTabLabel", "lensTMNotebookTabLabel")- ]- ''TMNotebookTab- )-+-- | This holds the GTK 'Notebook' containing multiple tabs of 'Terminal's. We+-- keep a separate list of terminals in 'tmNotebookTabs'. data TMNotebook = TMNotebook { tmNotebook :: !Notebook+ -- ^ This is the GTK 'Notebook' that holds multiple tabs of 'Terminal's. , tmNotebookTabs :: !(FocusList TMNotebookTab)+ -- ^ A 'FocusList' containing references to each individual 'TMNotebookTab'. } instance Show TMNotebook where@@ -96,28 +100,12 @@ showsPrec (d + 1) tmNotebookTabs . showString "}" -$(makeLensesFor- [ ("tmNotebook", "lensTMNotebook")- , ("tmNotebookTabs", "lensTMNotebookTabs")- ]- ''TMNotebook- )--data UserRequestedExit = UserRequestedExit | UserDidNotRequestExit deriving (Eq, Show)- data TMState' = TMState { tmStateApp :: !Application , tmStateAppWin :: !ApplicationWindow , tmStateNotebook :: !TMNotebook , tmStateFontDesc :: !FontDescription , tmStateConfig :: !TMConfig- , tmStateUserReqExit :: !UserRequestedExit- -- ^ This signifies whether or not the user has requested that Termonad- -- exit by either closing all terminals or clicking the exit button. If so,- -- 'tmStateUserReqExit' should have a value of 'UserRequestedExit'. However,- -- if the window manager requested Termonad to exit (probably through the user- -- trying to close Termonad through their window manager), then this will be- -- set to 'UserDidNotRequestExit'. } instance Show TMState' where@@ -139,22 +127,8 @@ showString ", " . showString "tmStateConfig = " . showsPrec (d + 1) tmStateConfig .- showString ", " .- showString "tmStateUserReqExit = " .- showsPrec (d + 1) tmStateUserReqExit . showString "}" -$(makeLensesFor- [ ("tmStateApp", "lensTMStateApp")- , ("tmStateAppWin", "lensTMStateAppWin")- , ("tmStateNotebook", "lensTMStateNotebook")- , ("tmStateFontDesc", "lensTMStateFontDesc")- , ("tmStateConfig", "lensTMStateConfig")- , ("tmStateUserReqExit", "lensTMStateUserReqExit")- ]- ''TMState'- )- type TMState = MVar TMState' instance Eq TMTerm where@@ -178,6 +152,16 @@ unq <- newUnique pure $ createTMTerm trm pd unq +getFocusedTermFromState :: TMState -> IO (Maybe Terminal)+getFocusedTermFromState mvarTMState =+ withMVar mvarTMState go+ where+ go :: TMState' -> IO (Maybe Terminal)+ go tmState = do+ let maybeNotebookTab =+ getFocusItemFL $ tmNotebookTabs $ tmStateNotebook tmState+ pure $ fmap (term . tmNotebookTabTerm) maybeNotebookTab+ createTMNotebookTab :: Label -> ScrolledWindow -> TMTerm -> TMNotebookTab createTMNotebookTab tabLabel scrollWin trm = TMNotebookTab@@ -196,6 +180,16 @@ createEmptyTMNotebook :: Notebook -> TMNotebook createEmptyTMNotebook notebook = createTMNotebook notebook emptyFL +notebookToList :: Notebook -> IO [Widget]+notebookToList notebook =+ unfoldHelper 0 []+ where unfoldHelper :: Int32 -> [Widget] -> IO [Widget]+ unfoldHelper index32 acc = do+ notePage <- notebookGetNthPage notebook index32+ case notePage of+ Nothing -> pure acc+ Just notePage' -> unfoldHelper (index32 + 1) (acc ++ [notePage'])+ newTMState :: TMConfig -> Application -> ApplicationWindow -> TMNotebook -> FontDescription -> IO TMState newTMState tmConfig app appWin note fontDesc = newMVar $@@ -205,7 +199,6 @@ , tmStateNotebook = note , tmStateFontDesc = fontDesc , tmStateConfig = tmConfig- , tmStateUserReqExit = UserDidNotRequestExit } newEmptyTMState :: TMConfig -> Application -> ApplicationWindow -> Notebook -> FontDescription -> IO TMState@@ -217,7 +210,6 @@ , tmStateNotebook = createEmptyTMNotebook note , tmStateFontDesc = fontDesc , tmStateConfig = tmConfig- , tmStateUserReqExit = UserDidNotRequestExit } newTMStateSingleTerm ::@@ -243,32 +235,334 @@ tmState <- readMVar mvarTMState print tmState -pTraceShowMTMState :: TMState -> IO ()-pTraceShowMTMState mvarTMState = do- tmState <- readMVar mvarTMState- pPrint tmState+------------+-- Config --+------------ -getFocusedTermFromState :: TMState -> IO (Maybe Terminal)-getFocusedTermFromState mvarTMState = do- withMVar- mvarTMState- ( pure .- firstOf- ( lensTMStateNotebook .- lensTMNotebookTabs .- focusItemGetter .- traverse .- lensTMNotebookTabTerm .- lensTerm- )- )+-- | The font size for the Termonad terminal. There are two ways to set the+-- fontsize, corresponding to the two different ways to set the font size in+-- the Pango font rendering library.+--+-- If you're not sure which to use, try 'FontSizePoints' first and see how it+-- looks. It should generally correspond to font sizes you are used to from+-- other applications.+data FontSize+ = FontSizePoints Int+ -- ^ This sets the font size based on \"points\". The conversion between a+ -- point and an actual size depends on the system configuration and the+ -- output device. The function 'GI.Pango.fontDescriptionSetSize' is used+ -- to set the font size. See the documentation for that function for more+ -- info.+ | FontSizeUnits Double+ -- ^ This sets the font size based on \"device units\". In general, this+ -- can be thought of as one pixel. The function+ -- 'GI.Pango.fontDescriptionSetAbsoluteSize' is used to set the font size.+ -- See the documentation for that function for more info.+ deriving (Eq, Show) -setUserRequestedExit :: TMState -> IO ()-setUserRequestedExit mvarTMState = do- modifyMVar_ mvarTMState $ \tmState -> do- pure $ tmState & lensTMStateUserReqExit .~ UserRequestedExit+-- | The default 'FontSize' used if not specified.+--+-- >>> defaultFontSize+-- FontSizePoints 12+defaultFontSize :: FontSize+defaultFontSize = FontSizePoints 12 -getUserRequestedExit :: TMState -> IO UserRequestedExit-getUserRequestedExit mvarTMState = do+-- | Settings for the font to be used in Termonad.+data FontConfig = FontConfig+ { fontFamily :: !Text+ -- ^ The font family to use. Example: @"DejaVu Sans Mono"@ or @"Source Code Pro"@+ , fontSize :: !FontSize+ -- ^ The font size.+ } deriving (Eq, Show)++-- | The default 'FontConfig' to use if not specified.+--+-- >>> defaultFontConfig == FontConfig {fontFamily = "Monospace", fontSize = defaultFontSize}+-- True+defaultFontConfig :: FontConfig+defaultFontConfig =+ FontConfig+ { fontFamily = "Monospace"+ , fontSize = defaultFontSize+ }++-- | This data type represents an option that can either be 'Set' or 'Unset'.+--+-- This data type is used in situations where leaving an option unset results+-- in a special state that is not representable by setting any specific value.+--+-- Examples of this include the 'cursorFgColour' and 'cursorBgColour' options+-- supplied by the 'ColourConfig' @ConfigExtension@. By default,+-- 'cursorFgColour' and 'cursorBgColour' are both 'Unset'. However, when+-- 'cursorBgColour' is 'Set', 'cursorFgColour' defaults to the color of the text+-- underneath. There is no way to represent this by setting 'cursorFgColour'.+data Option a = Unset | Set !a+ deriving (Show, Read, Eq, Ord, Functor, Foldable)++-- | Run a function over the value contained in an 'Option'. Return 'mempty'+-- when 'Option' is 'Unset'.+--+-- >>> whenSet (Set [1,2,3]) (++ [4,5,6]) :: [Int]+-- [1,2,3,4,5,6]+-- >>> whenSet Unset (++ [4,5,6]) :: [Int]+-- []+whenSet :: Monoid m => Option a -> (a -> m) -> m+whenSet = \case+ Unset -> \_ -> mempty+ Set x -> \f -> f x++-- | Whether or not to show the scroll bar in a terminal.+data ShowScrollbar+ = ShowScrollbarNever -- ^ Never show the scroll bar, even if there are too+ -- many lines on the terminal to show all at once. You+ -- should still be able to scroll with the mouse wheel.+ | ShowScrollbarAlways -- ^ Always show the scrollbar, even if it is not+ -- needed.+ | ShowScrollbarIfNeeded -- ^ Only show the scrollbar if there are too many+ -- lines on the terminal to show all at once.+ deriving (Eq, Show)++-- | Whether or not to show the tab bar for switching tabs.+data ShowTabBar+ = ShowTabBarNever -- ^ Never show the tab bar, even if there are multiple tabs+ -- open. This may be confusing if you plan on using multiple tabs.+ | ShowTabBarAlways -- ^ Always show the tab bar, even if you only have one tab open.+ | ShowTabBarIfNeeded -- ^ Only show the tab bar if you have multiple tabs open.+ deriving (Eq, Show)++-- | Configuration options for Termonad.+--+-- See 'defaultConfigOptions' for the default values.+data ConfigOptions = ConfigOptions+ { fontConfig :: !FontConfig+ -- ^ Specific options for fonts.+ , showScrollbar :: !ShowScrollbar+ -- ^ When to show the scroll bar.+ , scrollbackLen :: !Integer+ -- ^ The number of lines to keep in the scroll back history for each terminal.+ , confirmExit :: !Bool+ -- ^ Whether or not to ask you for confirmation when closing individual+ -- terminals or Termonad itself. It is generally safer to keep this as+ -- 'True'.+ , wordCharExceptions :: !Text+ -- ^ When double-clicking on text in the terminal with the mouse, Termonad+ -- will use this value to determine what to highlight. The individual+ -- characters in this list will be counted as part of a word.+ --+ -- For instance if 'wordCharExceptions' is @""@, then when you double-click+ -- on the text @http://@, only the @http@ portion will be highlighted. If+ -- 'wordCharExceptions' is @":"@, then the @http:@ portion will be+ -- highlighted.+ , showMenu :: !Bool+ -- ^ Whether or not to show the @File@ @Edit@ etc menu.+ , showTabBar :: !ShowTabBar+ -- ^ When to show the tab bar.+ , cursorBlinkMode :: !CursorBlinkMode+ -- ^ How to handle cursor blink.+ } deriving (Eq, Show)++-- | The default 'ConfigOptions'.+--+-- >>> :{+-- let defConfOpt =+-- ConfigOptions+-- { fontConfig = defaultFontConfig+-- , showScrollbar = ShowScrollbarIfNeeded+-- , scrollbackLen = 10000+-- , confirmExit = True+-- , wordCharExceptions = "-#%&+,./=?@\\_~\183:"+-- , showMenu = True+-- , showTabBar = ShowTabBarIfNeeded+-- , cursorBlinkMode = CursorBlinkModeOn+-- }+-- in defaultConfigOptions == defConfOpt+-- :}+-- True+defaultConfigOptions :: ConfigOptions+defaultConfigOptions =+ ConfigOptions+ { fontConfig = defaultFontConfig+ , showScrollbar = ShowScrollbarIfNeeded+ , scrollbackLen = 10000+ , confirmExit = True+ , wordCharExceptions = "-#%&+,./=?@\\_~\183:"+ , showMenu = True+ , showTabBar = ShowTabBarIfNeeded+ , cursorBlinkMode = CursorBlinkModeOn+ }++-- | The Termonad 'ConfigOptions' along with the 'ConfigHooks'.+data TMConfig = TMConfig+ { options :: !ConfigOptions+ , hooks :: !ConfigHooks+ } deriving Show++-- | The default 'TMConfig'.+--+-- 'options' is 'defaultConfigOptions' and 'hooks' is 'defaultConfigHooks'.+defaultTMConfig :: TMConfig+defaultTMConfig =+ TMConfig+ { options = defaultConfigOptions+ , hooks = defaultConfigHooks+ }++---------------------+-- ConfigHooks --+---------------------++-- | Hooks into certain termonad operations and VTE events. Used to modify+-- termonad's behaviour in order to implement new functionality. Fields should+-- have sane @Semigroup@ and @Monoid@ instances so that config extensions can+-- be combined uniformly and new hooks can be added without incident.+data ConfigHooks = ConfigHooks {+ -- | Produce an IO action to run on creation of new @Terminal@, given @TMState@+ -- and the @Terminal@ in question.+ createTermHook :: TMState -> Terminal -> IO ()+}++instance Show ConfigHooks where+ showsPrec :: Int -> ConfigHooks -> ShowS+ showsPrec _ _ =+ showString "ConfigHooks {" .+ showString "createTermHook = <function>" .+ showString "}"++-- | Default values for the 'ConfigHooks'.+--+-- - The default function for 'createTermHook' is 'defaultCreateTermHook'.+defaultConfigHooks :: ConfigHooks+defaultConfigHooks =+ ConfigHooks+ { createTermHook = defaultCreateTermHook+ }++-- | Default value for 'createTermHook'. Does nothing.+defaultCreateTermHook :: TMState -> Terminal -> IO ()+defaultCreateTermHook _ _ = pure ()++----------------+-- Invariants --+----------------++data FocusNotSameErr+ = FocusListFocusExistsButNoNotebookTabWidget+ | NotebookTabWidgetDiffersFromFocusListFocus+ | NotebookTabWidgetExistsButNoFocusListFocus+ deriving Show++data TabsDoNotMatch+ = TabLengthsDifferent Int Int -- ^ The first 'Int' is the number of tabs in the+ -- actual GTK 'Notebook'. The second 'Int' is+ -- the number of tabs in the 'FocusList'.+ | TabAtIndexDifferent Int -- ^ The tab at index 'Int' is different between+ -- the actual GTK 'Notebook' and the 'FocusList'.+ deriving (Show)++data TMStateInvariantErr+ = FocusNotSame FocusNotSameErr Int+ | TabsDoNotMatch TabsDoNotMatch+ deriving Show++-- | Gather up the invariants for 'TMState' and return them as a list.+--+-- If no invariants have been violated, then this function should return an+-- empty list.+invariantTMState' :: TMState' -> IO [TMStateInvariantErr]+invariantTMState' tmState =+ runInvariants+ [ invariantFocusSame+ , invariantTMTabLength+ , invariantTabsAllMatch+ ]+ where+ runInvariants :: [IO (Maybe TMStateInvariantErr)] -> IO [TMStateInvariantErr]+ runInvariants = fmap catMaybes . sequence++ invariantFocusSame :: IO (Maybe TMStateInvariantErr)+ invariantFocusSame = do+ let tmNote = tmNotebook $ tmStateNotebook tmState+ index32 <- notebookGetCurrentPage tmNote+ maybeWidgetFromNote <- notebookGetNthPage tmNote index32+ let focusList = tmNotebookTabs $ tmStateNotebook tmState+ maybeScrollWinFromFL =+ fmap tmNotebookTabTermContainer $ getFocusItemFL $ focusList+ idx = fromIntegral index32+ case (maybeWidgetFromNote, maybeScrollWinFromFL) of+ (Nothing, Nothing) -> pure Nothing+ (Just _, Nothing) ->+ pure $+ Just $+ FocusNotSame NotebookTabWidgetExistsButNoFocusListFocus idx+ (Nothing, Just _) ->+ pure $+ Just $+ FocusNotSame FocusListFocusExistsButNoNotebookTabWidget idx+ (Just widgetFromNote, Just scrollWinFromFL) -> do+ isEq <- widgetEq widgetFromNote scrollWinFromFL+ if isEq+ then pure Nothing+ else+ pure $+ Just $+ FocusNotSame NotebookTabWidgetDiffersFromFocusListFocus idx++ invariantTMTabLength :: IO (Maybe TMStateInvariantErr)+ invariantTMTabLength = do+ let tmNote = tmNotebook $ tmStateNotebook tmState+ noteLength32 <- notebookGetNPages tmNote+ let noteLength = fromIntegral noteLength32+ focusListLength = lengthFL $ tmNotebookTabs $ tmStateNotebook tmState+ lengthEqual = focusListLength == noteLength+ if lengthEqual+ then pure Nothing+ else pure $+ Just $+ TabsDoNotMatch $+ TabLengthsDifferent noteLength focusListLength++ -- Turns a FocusList and Notebook into two lists of widgets and compares each widget for equality+ invariantTabsAllMatch :: IO (Maybe TMStateInvariantErr)+ invariantTabsAllMatch = do+ let tmNote = tmNotebook $ tmStateNotebook tmState+ focusList = tmNotebookTabs $ tmStateNotebook tmState+ flList = fmap tmNotebookTabTermContainer $ toList focusList+ noteList <- notebookToList tmNote+ tabsMatch noteList flList+ where+ tabsMatch+ :: forall a b+ . (IsWidget a, IsWidget b)+ => [a]+ -> [b]+ -> IO (Maybe TMStateInvariantErr)+ tabsMatch xs ys = foldr go (pure Nothing) (zip3 xs ys [0..])+ where+ go :: (a, b, Int) -> IO (Maybe TMStateInvariantErr) -> IO (Maybe TMStateInvariantErr)+ go (x, y, i) acc = do+ isEq <- widgetEq x y+ if isEq+ then acc+ else pure . Just $ TabsDoNotMatch (TabAtIndexDifferent i)++-- | Check the invariants for 'TMState', and call 'fail' if we find that they+-- have been violated.+assertInvariantTMState :: TMState -> IO ()+assertInvariantTMState mvarTMState = do tmState <- readMVar mvarTMState- pure $ tmState ^. lensTMStateUserReqExit+ assertValue <- invariantTMState' tmState+ case assertValue of+ [] x-> pure ()+ errs@(_:_) -> do+ putStrLn "In assertInvariantTMState, some invariants for TMState are being violated."+ putStrLn "\nInvariants violated:"+ print errs+ putStrLn "\nTMState:"+ pPrint tmState+ putStrLn ""+ fail "Invariants violated for TMState"++pPrintTMState :: TMState -> IO ()+pPrintTMState mvarTMState = do+ tmState <- readMVar mvarTMState+ pPrint tmState
termonad.cabal view
@@ -1,5 +1,5 @@ name: termonad-version: 0.2.1.0+version: 1.0.0.0 synopsis: Terminal emulator configurable in Haskell description: Please see <https://github.com/cdepillabout/termonad#readme README.md>. homepage: https://github.com/cdepillabout/termonad@@ -17,9 +17,8 @@ , img/termonad.png , .nix-helpers/nixops.nix , .nix-helpers/nixpkgs.nix- , .nix-helpers/running-termonad.nix , .nix-helpers/stack-nix-shell.nix- , .nix-helpers/termonad.nix+ , .nix-helpers/termonad-with-packages.nix , shell.nix data-files: img/termonad-lambda.png custom-setup@@ -27,60 +26,90 @@ , Cabal , cabal-doctest >=1.0.2 && <1.1 +-- This flag builds the example code in the example-config/ directory, as well+-- as the example from the README.md file. It is only used for testing. It+-- should be enabled for CI.+flag buildexamples+ description: Build an executable from the examples in the example-config/+ directory, as well as the example from the README.md file. This+ is normally only used for testing.+ default: False+ library hs-source-dirs: src exposed-modules: Termonad , Termonad.App , Termonad.Config- , Termonad.FocusList+ , Termonad.Config.Colour+ , Termonad.Config.Vec , Termonad.Gtk , Termonad.Keys+ , Termonad.Lenses , Termonad.Prelude , Termonad.Term , Termonad.Types , Termonad.XML other-modules: Paths_termonad build-depends: base >= 4.7 && < 5+ , adjunctions , classy-prelude , colour , constraints+ , containers , data-default , directory >= 1.3.1.0+ , distributive , dyre , filepath+ , focuslist , gi-gdk , gi-gio , gi-glib , gi-gtk >= 3.0.24 , gi-pango , gi-vte >= 2.91.19- , haskell-gi-base+ , haskell-gi-base >= 0.21.2 , lens+ , mono-traversable , pretty-simple , QuickCheck+ , singletons , xml-conduit , xml-html-qq default-language: Haskell2010 ghc-options: -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates default-extensions: DataKinds+ , DefaultSignatures+ , DeriveAnyClass+ , DeriveFoldable+ , DeriveFunctor+ , DerivingStrategies+ , EmptyCase+ , ExistentialQuantification+ , FlexibleContexts+ , FlexibleInstances , GADTs , GeneralizedNewtypeDeriving , InstanceSigs , KindSignatures+ , LambdaCase+ , MultiParamTypeClasses , NamedFieldPuns , NoImplicitPrelude- , OverloadedStrings , OverloadedLabels , OverloadedLists+ , OverloadedStrings , PatternSynonyms , PolyKinds , RankNTypes , RecordWildCards , ScopedTypeVariables+ , StandaloneDeriving , TypeApplications , TypeFamilies , TypeOperators other-extensions: TemplateHaskell+ , UndecidableInstances pkgconfig-depends: gtk+-3.0 executable termonad@@ -106,12 +135,18 @@ type: exitcode-stdio-1.0 main-is: Test.hs hs-source-dirs: test+ -- other-modules: Test.FocusList+ -- , Test.FocusList.Invariants build-depends: base+ , genvalidity-containers+ , genvalidity-hspec , hedgehog , lens+ , QuickCheck , termonad , tasty , tasty-hedgehog+ , tasty-hspec default-language: Haskell2010 ghc-options: -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -threaded -rtsopts -with-rtsopts=-N default-extensions: DataKinds@@ -133,6 +168,37 @@ , TypeFamilies , TypeOperators other-extensions: TemplateHaskell++executable termonad-readme+ main-is: README.lhs+ hs-source-dirs: test/readme+ build-depends: base+ , markdown-unlit+ , termonad+ , colour+ ghc-options: -pgmL markdown-unlit+ default-language: Haskell2010++ if flag(buildexamples)+ buildable: True+ else+ buildable: False++executable termonad-example-colour-extension+ main-is: example-config/ExampleColourExtension.hs+ build-depends: base+ , termonad+ , colour+ default-language: Haskell2010++ if flag(buildexamples)+ buildable: True+ else+ buildable: False++source-repository head+ type: git+ location: https://github.com/cdepillabout/termonad/ -- benchmark termonad-bench -- type: exitcode-stdio-1.0
test/Test.hs view
@@ -3,36 +3,8 @@ import Termonad.Prelude -import Control.Lens ((^.))-import Hedgehog- ( Gen- , Property- , PropertyT- , annotate- , annotateShow- , failure- , forAll- , property- , success- )-import Hedgehog.Gen (alphaNum, choice, int, string)-import Hedgehog.Range (constant, linear) import Test.Tasty (TestTree, defaultMain, testGroup)-import Test.Tasty.Hedgehog (testProperty) -import Termonad.FocusList- ( FocusList- , debugFL- , deleteFL- , emptyFL- , insertFL- , invariantFL- , isEmptyFL- , lensFocusListLen- , lookupFL- , removeFL- )- main :: IO () main = do tests <- testsIO@@ -43,105 +15,5 @@ pure $ testGroup "tests"- [ testProperty "invariants in FocusList" testInvariantsInFocusList+ [ -- focusListTests ]--testInvariantsInFocusList :: Property-testInvariantsInFocusList =- property $ do- numOfActions <- forAll $ int (linear 1 200)- let initialState = emptyFL- let strGen = string (constant 0 25) alphaNum- -- traceM "----------------------------------"- -- traceM $ "starting bar, numOfActions: " <> show numOfActions- runActions numOfActions strGen initialState--data Action a- = InsertFL Int a- | RemoveFL Int- | DeleteFL a- deriving (Eq, Show)--genInsertFL :: Gen a -> FocusList a -> Maybe (Gen (Action a))-genInsertFL valGen fl- | isEmptyFL fl = Just $ do- val <- valGen- pure $ InsertFL 0 val- | otherwise = Just $ do- let len = fl ^. lensFocusListLen- key <- int $ constant 0 len- val <- valGen- pure $ InsertFL key val--genRemoveFL :: FocusList a -> Maybe (Gen (Action a))-genRemoveFL fl- | isEmptyFL fl = Nothing- | otherwise = Just $ do- let len = fl ^. lensFocusListLen- keyToRemove <- int $ constant 0 (len - 1)- pure $ RemoveFL keyToRemove--genDeleteFL :: Show a => FocusList a -> Maybe (Gen (Action a))-genDeleteFL fl- | isEmptyFL fl = Nothing- | otherwise = Just $ do- let len = fl ^. lensFocusListLen- keyForItemToDelete <- int $ constant 0 (len - 1)- let maybeItemToDelete = lookupFL keyForItemToDelete fl- case maybeItemToDelete of- Nothing ->- let msg =- "Could not find item in focuslist even though " <>- "it should be there." <>- "\nkey: " <>- show keyForItemToDelete <>- "\nfocus list: " <>- debugFL fl- in error msg- Just item -> pure $ DeleteFL item--generateAction :: Show a => Gen a -> FocusList a -> Gen (Action a)-generateAction valGen fl = do- let generators =- catMaybes- [ genInsertFL valGen fl- , genRemoveFL fl- , genDeleteFL fl- ]- case generators of- [] ->- let msg =- "No generators available for fl:\n" <>- debugFL fl- in error msg- _ -> do- choice generators--performAction :: Eq a => FocusList a -> Action a -> Maybe (FocusList a)-performAction fl (InsertFL key val) = insertFL key val fl-performAction fl (RemoveFL keyToRemove) = removeFL keyToRemove fl-performAction fl (DeleteFL valToDelete) = Just $ deleteFL valToDelete fl--runActions :: (Eq a, Monad m, Show a) => Int -> Gen a -> FocusList a -> PropertyT m ()-runActions i valGen startingFL- | i <= 0 = success- | otherwise = do- action <- forAll $ generateAction valGen startingFL- -- traceM $ "runActions, startingFL: " <> show startingFL- -- traceM $ "runActions, action: " <> show action- let maybeEndingFL = performAction startingFL action- case maybeEndingFL of- Nothing -> do- annotate "Failed to perform action."- annotateShow startingFL- annotateShow action- failure- Just endingFL ->- if invariantFL endingFL- then runActions (i - 1) valGen endingFL- else do- annotate "Ending FocusList failed invariants."- annotateShow startingFL- annotateShow action- annotateShow endingFL- failure
+ test/readme/README.lhs view
@@ -0,0 +1,405 @@++Termonad+=========++[](http://travis-ci.org/cdepillabout/termonad)+[](https://hackage.haskell.org/package/termonad)+[](http://stackage.org/lts/package/termonad)+[](http://stackage.org/nightly/package/termonad)+[](./LICENSE)+[](https://gitter.im/termonad/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)+[](https://webchat.freenode.net/)++Termonad is a terminal emulator configurable in Haskell. It is extremely+customizable and provides hooks to modify the default behavior. It can be+thought of as the "XMonad" of terminal emulators.++++<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->+**Table of Contents**++- [Termonad](#termonad)+ - [Installation](#installation)+ - [Arch Linux](#arch-linux)+ - [Ubuntu / Debian](#ubuntu--debian)+ - [Nix](#nix)+ - [Mac OS X](#mac-os-x)+ - [Installing with just `stack`](#installing-with-just-stack)+ - [Installing with just `nix`](#installing-with-just-nix)+ - [Installing with `stack` using `nix`](#installing-with-stack-using-nix)+ - [Windows](#windows)+ - [How to use Termonad](#how-to-use-termonad)+ - [Default Keybindings](#default-keybindings)+ - [Configuring Termonad](#configuring-termonad)+ - [Compiling Local Settings](#compiling-local-settings)+ - [Running with `stack`](#running-with-stack)+ - [Running with `nix`](#running-with-nix)+ - [Goals](#goals)+ - [Where to get help](#where-to-get-help)+ - [Contributions](#contributions)+ - [Maintainers](#maintainers)++<!-- markdown-toc end -->++## Installation++Termonad can be installed on any system as long as the necessary GTK libraries+are available. The following are instructions for installing Termonad on a few+different distributions and systems. If the given steps don't work for you, or+you want to add instructions for an additional system, please send a pull+request.++The following steps use the+[`stack`](https://docs.haskellstack.org/en/stable/README/) build tool to build+Termonad, but [`cabal`](https://www.haskell.org/cabal/) can be used as well. Steps for+installing `stack` can be found on+[this page](https://docs.haskellstack.org/en/stable/install_and_upgrade/).+++### Arch Linux++First, you must install the required GTK system libraries:++```sh+$ pacman -S vte3+```++In order to install Termonad, clone this repository and run `stack install`.+This will install the `termonad` binary to `~/.local/bin/`:++```sh+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ stack install+```++### Ubuntu / Debian++First, you must install the required GTK system libraries:++```sh+$ apt-get install gobject-introspection libgirepository1.0-dev libgtk-3-dev libvte-2.91-dev+```++In order to install Termonad, clone this repository and run `stack install`.+This will install the `termonad` binary to `~/.local/bin/`:++```sh+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ stack install+```++### Nix++If you have `nix` installed, you should be able to use it to build Termonad.+This means that it will work on NixOS, or with `nix` on another distro. There+are two different ways to use `nix` to build Termonad:++The first is using `stack`. The following commands install `stack` for your+user, clone this repository, and install the `termonad` binary to `~/.local/bin/`:++```sh+$ nix-env -i stack+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ stack --nix install+```++The second is using the normal `nix-build` machinery. The following commands+clone this repository and build the `termonad` binary at `./result/bin/`:++```sh+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ nix-build+```++### Mac OS X++Building and installing Termonad on Mac OS X should be possible with any of the following three methods:++- Install the required system libraries (like GTK and VTE) by hand, then use+ `stack` to build Termonad.++ This is probably the easiest method. You don't have to understand anything+ about `nix`. However, it is slightly annoying to have to install GTK and+ VTE by hand.++- Use `nix` to install both the required system libraries and Termonad itself.++ If you are a nix user and want an easy way to install Termonad, this+ is the recommended method.++- Use `nix` to install install the required system libraries, and `stack` to+ build Termonad.++ If you are a nix user, but want to use `stack` to actually do development+ on Termonad, using `stack` may be easier than using `cabal`.++The following sections describe each method.++#### Installing with just `stack`++(*currently no instructions available. please send a PR adding instructions if you get termonad to build using this method.*)++#### Installing with just `nix`++`nix` can be used to install Termonad with the following steps, assuming you+have `nix` [installed](https://nixos.org/nix/download.html). These commands+clone this repository and build the `termonad` binary at `./result/bin/`:++```sh+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ nix-build+```++#### Installing with `stack` using `nix`++`stack` can be used in conjunction with `nix` to install Termonad. `nix` will+handle installing system dependencies (like GTK and VTE), while `stack` will+handle compiling and installing Haskell packages.++You must have `nix` [installed](https://nixos.org/nix/download.html).++You will also need `stack` installed. You can do that with the following command:++```sh+$ nix-env -i stack+```++After `stack` is installed, you will need to clone Termonad and build it:++```+$ git clone https://github.com/cdepillabout/termonad+$ cd termonad/+$ stack --nix install+```++This will install the `termonad` binary to `~/.local/bin/`.++### Windows++(*currently no instructions available. please send a PR adding instructions if you get termonad to build.*)++## How to use Termonad++Termonad is similar to XMonad. The above steps will install a `termonad` binary+somewhere on your system. If you have installed Termonad using `stack`, the+`termonad` binary will be in `~/.local/bin/`. This binary is a version of+Termonad configured with default settings. You can try running it to get an idea+of what Termonad is like:++```sh+$ ~/.local/bin/termonad+```++The following section describes the default keybindings.++If you would like to configure Termonad with your own settings, first you will+need to create a Haskell file called `~/.config/termonad/termonad.hs`. A following+section gives an example configuration file.++If this configuration file exists, when the `~/.local/bin/termonad` binary+launches, it will try to use GHC to compile the configuration file. If GHC+is able to successfully compile the configuration file, a separate binary will+be created called something like `~/.cache/termonad/termonad-linux-x86_64`.+This binary file can be thought of as your own personal Termonad, configured+with all your own settings.++When you run `~/.local/bin/termonad`, it will re-exec+`~/.cache/termonad/termonad-linux-x86_64` if it exists.++However, there is one difficulty with this setup. In order for the+`~/.local/bin/termonad` binary to be able to compile your+`~/.config/termonad/termonad.hs` configuration file, Termonad needs to know+where GHC is, as well as where all your Haskell packages live. This presents+some difficulties that will be discussed in a following section.++### Default Keybindings++Termonad provides the following default key bindings.++| Keybinding | Action |+|------------|--------|+| <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>t</kbd> | Open new tab. |+| <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>w</kbd> | Close tab. |+| <kbd>Alt</kbd> <kbd>(number key)</kbd> | Switch to tab `number`. For example, <kbd>Alt</kbd> <kbd>2</kbd> switches to tab 2. |++### Configuring Termonad++The following is an example Termonad configuration file. You should save this to+`~/.config/termonad/termonad.hs`. You can find more information on the available+configuration options within the+[`Termonad.Config`](https://hackage.haskell.org/package/termonad/docs/Termonad-Config.html)+module.++```haskell+{-# LANGUAGE OverloadedStrings #-}++module Main where++import Data.Colour.SRGB (Colour, sRGB24)+import Termonad.App (defaultMain)+import Termonad.Config+ ( FontConfig, FontSize(FontSizePoints), Option(Set)+ , ShowScrollbar(ShowScrollbarAlways), defaultConfigOptions, defaultFontConfig+ , defaultTMConfig, fontConfig, fontFamily, fontSize, options, showScrollbar+ )+import Termonad.Config.Colour+ (ColourConfig, addColourExtension, createColourExtension, cursorBgColour+ , defaultColourConfig+ )++-- | This sets the color of the cursor in the terminal.+--+-- This uses the "Data.Colour" module to define a dark-red color.+-- There are many default colors defined in "Data.Colour.Names".+cursBgColor :: Colour Double+cursBgColor = sRGB24 204 0 0++-- | This sets the colors used for the terminal. We only specify the background+-- color of the cursor.+colConf :: ColourConfig (Colour Double)+colConf =+ defaultColourConfig+ { cursorBgColour = Set cursBgColor+ }++-- | This defines the font for the terminal.+fontConf :: FontConfig+fontConf =+ defaultFontConfig+ { fontFamily = "DejaVu Sans Mono"+ , fontSize = FontSizePoints 13+ }++main :: IO ()+main = do+ colExt <- createColourExtension colConf+ let termonadConf =+ defaultTMConfig+ { options =+ defaultConfigOptions+ { fontConfig = fontConf+ -- Make sure the scrollbar is always visible.+ , showScrollbar = ShowScrollbarAlways+ }+ }+ `addColourExtension` colExt+ defaultMain termonadConf+```++### Compiling Local Settings++If you launch Termonad by calling `~/.local/bin/termonad`, it will try to+compile the `~/.config/termonad/termonad.hs` file if it exists. The problem is+that `~/.local/bin/termonad` needs to be able to see GHC and the required+Haskell libraries to be able to compile `~/.config/termonad/termonad.hs`.++There are a couple solutions to this problem, listed in the sections below.++(These steps are definitely confusing. I would love to figure out a better+way to do this. Please submit an issue or PR if you have a good idea about+how to fix this.)++#### Running with `stack`++If you originally compiled Termonad with `stack`, you can use `stack` to+execute Termonad. First, you must change to the directory with the Termonad+source code. From there, you can run `stack exec`:++```sh+$ cd termonad/ # change to the termonad source code directory+$ stack exec -- termonad+```++`stack` will pick up the correct GHC version and libraries from the+`stack.yaml` and `termonad.cabal` file. `termonad` will be run in an+environment with GHC available. `termonad` will use this GHC and libraries to+compile your `~/.config/termonad/termonad.hs` file. It if succeeds, it should+create a `~/.cache/termonad/termonad-linux-x86_64` binary.++If you need extra Haskell libraries available when compiling your+`~/.config/termonad/termonad.hs` file, you can specify them to `stack exec`:++```sh+$ stack exec --package lens --package conduit -- termonad+```++The problem with this is that `stack exec` changes quite a few of your+environment variables. It is not recommended to actually run Termonad from+within `stack exec`. After you run `stack exec -- termonad` and let it+recompile your `~/.config/termonad/termonad.hs` file, exit Termonad.+Re-run Termonad by calling it directly. Termonad will notice that+`~/.config/termonad/termonad.hs` hasn't changed since+`~/.cache/termonad/termonad-linux-x86_64` has been recompiled, so it will+directly execute `~/.cache/termonad/termonad-linux-x86_64`.++#### Running with `nix`++Building Termonad with `nix` (by running `nix-build` in the top+directory) sets it up so that Termonad can see GHC. Termonad should be able+to compile the `~/.config/termonad/termonad.hs` file by default.++If you're interested in how this works, or want to change which Haskell+packages are available from your `~/.config/termonad/termonad.hs` file, please+see the documentation in the+[`.nix-helpers/termonad-with-packages.nix`](./.nix-helpers/termonad-with-packages.nix)+file.++## Goals++Termonad has the following goals:++* fully configurable in Haskell++ There are already+ [many](https://gnometerminator.blogspot.com/p/introduction.html)+ [good](https://www.enlightenment.org/about-terminology.md)+ [terminal](http://software.schmorp.de/pkg/rxvt-unicode.html)+ [emulators](https://launchpad.net/sakura). However, there are no terminal+ emulators fully configurable in Haskell. Termonad fills this niche.++* flexible++ Most people only need a terminal emulator that lets you change the font-size,+ cursor color, etc. They don't need tons of configuration options. Termonad+ should be for people that like lots of configuration options. Termonad+ should provide many hooks to allow the user full control over its behavior.++* stable++ Termonad should be able to be used everyday as your main terminal+ emulator. It should not crash for any reason. If you experience a crash,+ please file an issue or a pull request!++* good documentation++ The [documentation](https://hackage.haskell.org/package/termonad) for+ Termonad on Hackage should be good. You shouldn't have to guess at what+ certain data types or functions do. If you have a hard time understanding+ anything in the documentation, please submit an issue or PR.++## Where to get help++If you find a bug in Termonad, please either+[send a PR](https://github.com/cdepillabout/termonad/pulls) fixing it or create+an [issue](https://github.com/cdepillabout/termonad/issues) explaining it.++If you just need help with configuring Termonad, you can either join the+[Gitter room](https://gitter.im/termonad/Lobby) or+[#termonad on irc.freenode.net](https://webchat.freenode.net/).++## Contributions++Contributions are highly appreciated. Termonad is currently missing many+helpful configuration options and behavior hooks. If there is something you+would like to add, please submit an issue or PR.++## Maintainers++- [cdepillabout](https://github.com/cdepillabout)+- [LSLeary](https://github.com/LSLeary)