ghcitui-0.1.0.0: lib/ghcitui-brick/Ghcitui/Brick/AppInterpState.hs
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE RecordWildCards #-}
module Ghcitui.Brick.AppInterpState
( AppInterpState (_liveEditor, _viewLock, _commandBuffer, historyPos)
, commandBuffer
, emptyAppInterpState
, futHistoryPos
, cmdHistory
, isScanningHist
, liveEditor
, pastHistoryPos
, pushHistory
, viewLock
) where
import qualified Brick.Widgets.Edit as BE
import qualified Data.Text as T
import Lens.Micro as Lens
data AppInterpState s n = AppInterpState
{ _liveEditor :: BE.Editor s n
, _viewLock :: !Bool
-- ^ Whether we're locked to the bottom of the interpreter (True) window or not (False).
, _commandBuffer :: [s]
-- ^ The text currently typed into the editor, but not yet executed or in the history.
, _cmdHistory :: [[s]]
, historyPos :: !Int
}
-- | Lens accessor for the editor. See '_liveEditor'.
liveEditor :: Lens.Lens' (AppInterpState s n) (BE.Editor s n)
liveEditor = Lens.lens _liveEditor (\ais le -> ais{_liveEditor = le})
-- | Lens for the view lock setting. See '_viewLock'.
viewLock :: Lens.Lens' (AppInterpState s n) Bool
viewLock = Lens.lens _viewLock (\ais x -> ais{_viewLock = x})
-- | Lens for the current contents of the command line buffer. See '_commandBuffer'.
commandBuffer :: Lens.Lens' (AppInterpState s n) [s]
commandBuffer = Lens.lens _commandBuffer (\ais x -> ais{_commandBuffer = x})
-- | Return the interpreter command history.
cmdHistory :: AppInterpState s n -> [[s]]
cmdHistory = _cmdHistory
-- | Create a base interpreter state.
emptyAppInterpState
:: n
-- ^ Name for the 'Brick.Editor'.
-> AppInterpState T.Text n
emptyAppInterpState name =
AppInterpState
{ _liveEditor = initInterpWidget name (Just 1)
, _viewLock = True
, _commandBuffer = mempty
, _cmdHistory = mempty
, historyPos = 0
}
resetHistoryPos :: AppInterpState s n -> AppInterpState s n
resetHistoryPos s = s{historyPos = 0}
-- | Move interpreter history back.
pastHistoryPos :: AppInterpState s n -> AppInterpState s n
pastHistoryPos s@AppInterpState{..} =
-- Note we do want it to stop at length _history, not length _history - 1
-- because 0 is not the beginning of the history, it's the commandBuffer.
s{historyPos = min (length _cmdHistory) $ succ historyPos}
-- | Are we currently viewing past contents?
isScanningHist :: AppInterpState s n -> Bool
isScanningHist AppInterpState{..} = historyPos /= 0
-- | Move interpreter history forward.
futHistoryPos :: AppInterpState s n -> AppInterpState s n
futHistoryPos s@AppInterpState{..} = s{historyPos = max 0 $ pred historyPos}
-- | Push a new value on to the history stack and reset the position.
pushHistory :: [s] -> AppInterpState s n -> AppInterpState s n
pushHistory cmdLines s = resetHistoryPos $ s{_cmdHistory = cmdLines : cmdHistory s}
-- | Create the initial live interpreter widget object.
initInterpWidget
:: n
-- ^ Editor name (must be a unique identifier).
-> Maybe Int
-- ^ Line height of the editor. Nothing for unlimited.
-> BE.Editor T.Text n
initInterpWidget name height = BE.editorText name height mempty