Skip to content

Commit

Permalink
Exception-safe reading of persistent state.
Browse files Browse the repository at this point in the history
In case of exception during reading of persistent state,
we ignore it and start with a fresh state.

Important after adding new state components.
  • Loading branch information
Michal J. Gajda committed Jul 26, 2012
1 parent 2233f24 commit ffa538c
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions yi/src/library/Yi/PersistentState.hs
Expand Up @@ -16,15 +16,17 @@ import System.FilePath((</>))
import System.Directory(getAppUserDataDirectory, doesFileExist)
import qualified Data.Map as M

import Control.Exc(ignoringException)

import Yi.Prelude
import Yi.Dynamic
import Yi.History
import Yi.Editor
import Yi.Keymap(YiM)
import Yi.Keymap.Vim.TagStack(VimTagStack(..), getTagStack, setTagStack)

data PersistentState = PersistentState { histories :: Histories
, vimTagStack :: VimTagStack
data PersistentState = PersistentState { histories :: !Histories
, vimTagStack :: !VimTagStack
}

$(derive makeBinary ''PersistentState)
Expand All @@ -44,7 +46,7 @@ getPersistentStateFilename :: YiM String
getPersistentStateFilename = do cfgDir <- io $ getAppUserDataDirectory "yi"
return $ cfgDir </> "history"

loadPersistentState, savePersistentState :: YiM ()
savePersistentState :: YiM ()
savePersistentState = do pStateFilename <- getPersistentStateFilename
(hist :: Histories) <- withEditor $ getA dynA
tagStack <- withEditor $ getTagStack
Expand All @@ -57,10 +59,20 @@ savePersistentState = do pStateFilename <- getPersistentStateFilename
trimH (History cur content prefix) = History cur (trim content) prefix
trim content = drop (max 0 (length content - maxHistory)) content

loadPersistentState = do pStateFilename <- getPersistentStateFilename
readPersistentState :: YiM (Maybe PersistentState)
readPersistentState = do pStateFilename <- getPersistentStateFilename
pStateExists <- io $ doesFileExist pStateFilename
when pStateExists $
do (pState :: PersistentState) <- io $ decodeFile pStateFilename
withEditor $ putA dynA $ histories pState
withEditor $ setTagStack $ vimTagStack pState
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 withEditor $ putA dynA $ histories pState
withEditor $ setTagStack $ vimTagStack pState

0 comments on commit ffa538c

Please sign in to comment.