module Yi.PersistentState(loadPersistentState,
savePersistentState,
maxHistoryEntries,
persistentSearch)
where
import Control.Monad
import Data.Typeable
import Data.Binary
#if __GLASGOW_HASKELL__ < 708
import Data.DeriveTH
#else
import GHC.Generics (Generic)
#endif
import Data.Default
import System.Directory(doesFileExist)
import qualified Data.Map as M
import Control.Exc(ignoringException)
import Control.Lens
import Yi.Config.Simple.Types(customVariable, Field)
import Yi.Editor
import Yi.History
import Yi.Keymap(YiM)
import Yi.KillRing(Killring(..))
import Yi.Paths(getPersistentStateFilename)
import Yi.Regex(SearchExp(..))
import Yi.Search.Internal (getRegexE, setRegexE)
import Yi.Utils
import Yi.Types (YiConfigVariable)
data PersistentState = PersistentState { histories :: !Histories
, aKillring :: !Killring
, aCurrentRegex :: Maybe SearchExp
}
#if __GLASGOW_HASKELL__ < 708
$(derive makeBinary ''PersistentState)
#else
deriving instance Generic PersistentState
instance Binary PersistentState
#endif
newtype MaxHistoryEntries = MaxHistoryEntries { _unMaxHistoryEntries :: Int }
deriving(Typeable, Binary)
instance Default MaxHistoryEntries where
def = MaxHistoryEntries 1000
instance YiConfigVariable MaxHistoryEntries
makeLenses ''MaxHistoryEntries
maxHistoryEntries :: Field Int
maxHistoryEntries = customVariable . unMaxHistoryEntries
newtype PersistentSearch = PersistentSearch { _unPersistentSearch :: Bool }
deriving(Typeable, Binary)
instance Default PersistentSearch where
def = PersistentSearch True
instance YiConfigVariable PersistentSearch
makeLenses ''PersistentSearch
persistentSearch :: Field Bool
persistentSearch = customVariable . unPersistentSearch
trimHistories :: Int -> Histories -> Histories
trimHistories maxHistory (Histories m) = Histories $ M.map trimH m
where
trimH (History cur content prefix) = History cur (trim content) prefix
trim content = drop (max 0 (length content maxHistory)) content
savePersistentState :: YiM ()
savePersistentState = do
MaxHistoryEntries histLimit <- withEditor askConfigVariableA
pStateFilename <- getPersistentStateFilename
(hist :: Histories) <- withEditor getEditorDyn
kr <- withEditor $ use killringA
curRe <- withEditor getRegexE
let pState = PersistentState {
histories = trimHistories histLimit hist
, aKillring = kr
, aCurrentRegex = curRe
}
io $ encodeFile pStateFilename pState
readPersistentState :: YiM (Maybe PersistentState)
readPersistentState = do pStateFilename <- getPersistentStateFilename
pStateExists <- io $ doesFileExist pStateFilename
if not pStateExists
then return Nothing
else io $ ignoringException $ strictDecoder pStateFilename
where
strictDecoder filename = do (state :: PersistentState) <- decodeFile filename
state `seq` return (Just state)
loadPersistentState :: YiM ()
loadPersistentState = do
maybePState <- readPersistentState
case maybePState of
Nothing -> return ()
Just pState -> do putEditorDyn $ histories pState
assign killringA $ aKillring pState
PersistentSearch keepSearch <- askConfigVariableA
when keepSearch . withEditor $
maybe (return ()) setRegexE $ aCurrentRegex pState