proteome-0.9.9.9: lib/Proteome/PersistBuffers.hs
module Proteome.PersistBuffers where
import Conc (Lock, lockOrSkip_)
import qualified Data.Text as Text (null)
import Exon (exon)
import qualified Log
import Path (Abs, Dir, File, Path, Rel, parseRelDir, relfile, toFilePath, (</>))
import Ribosome (Rpc, RpcError)
import Ribosome.Api (bufferGetName, vimCommand, vimGetCurrentBuffer)
import Ribosome.Api.Buffer (bufferForFile, buflisted, edit)
import qualified Ribosome.Data.FileBuffer as FileBuffer
import Ribosome.Effect.Persist (Persist)
import qualified Ribosome.Persist as Persist
import Proteome.Data.Env (Env)
import qualified Proteome.Data.Env as Env (buffers, mainProject)
import Proteome.Data.PersistBuffers (PersistBuffers (PersistBuffers))
import Proteome.Data.Project (Project (Project))
import Proteome.Data.ProjectMetadata (ProjectMetadata (DirProject))
import Proteome.Data.ProjectName (ProjectName (ProjectName))
import Proteome.Data.ProjectRoot (ProjectRoot (ProjectRoot))
import Proteome.Data.ProjectType (ProjectType (ProjectType))
import Proteome.Path (existingFile)
data StoreBuffersLock =
StoreBuffersLock
deriving stock (Eq, Show)
data LoadBuffersLock =
LoadBuffersLock
deriving stock (Eq, Show)
file :: Path Rel File
file =
[relfile|buffers.json|]
projectPaths ::
Member (AtomicState Env) r =>
Sem r (Maybe (Path Abs Dir, Path Rel Dir))
projectPaths =
examine <$> atomicGets Env.mainProject
where
examine (Project (DirProject (ProjectName name) (ProjectRoot root) (Just (ProjectType tpe))) _ _ _) =
(root,) <$> ((</>) <$> parseRelDir (toString tpe) <*> parseRelDir (toString name))
examine _ =
Nothing
storeBuffers ::
Member (Persist PersistBuffers) r =>
Members [Lock @@ StoreBuffersLock, AtomicState Env, Rpc, Rpc !! RpcError, Resource, Embed IO] r =>
Sem r ()
storeBuffers =
tag $ lockOrSkip_ $ projectPaths >>= traverse_ \ (cwd, path) -> do
names <- traverse bufferGetName =<< filterM buflisted =<< atomicGets Env.buffers
files <- catMaybes <$> traverse (existingFile cwd) names
Persist.store (Just (path </> file)) (PersistBuffers (listToMaybe files) files)
decodePersistBuffers ::
Member (Persist PersistBuffers) r =>
Path Rel Dir ->
Sem r (Maybe PersistBuffers)
decodePersistBuffers path =
Persist.load (Just (path </> file))
restoreBuffers ::
Members [Rpc, AtomicState Env, Log] r =>
PersistBuffers ->
Sem r ()
restoreBuffers (PersistBuffers active rest) = do
Log.debug [exon|Restoring buffers. Active: #{show active}|]
traverse_ loadActive active
traverse_ add rest
buffers <- traverse bufferForFile rest
atomicModify' (#buffers .~ (FileBuffer.buffer <$> catMaybes buffers))
where
add a =
vimCommand ("silent! badd " <> toText (toFilePath a))
loadActive path = do
currentBufferName <- bufferGetName =<< vimGetCurrentBuffer
when (Text.null currentBufferName) (edit path)
loadBuffers ::
Members [Persist PersistBuffers, Lock @@ LoadBuffersLock, Rpc, AtomicState Env, Log, Resource] r =>
Sem r ()
loadBuffers =
tag $ lockOrSkip_ $ projectPaths >>= traverse_ \ (_, path) ->
traverse_ restoreBuffers =<< decodePersistBuffers path