{-# language OverloadedStrings #-} module Rasa.Ext.Files ( files , save ) where import qualified Data.Text.IO as TIO import System.Environment import Data.Typeable import Data.Default import Data.Maybe import Control.Monad import Control.Monad.Trans import qualified Yi.Rope as Y import Rasa.Ext import Rasa.Ext.Views import Rasa.Ext.Cmd -- | Stores filename data FileInfo = FileInfo (Maybe String) deriving (Typeable, Show, Eq) instance Default FileInfo where def = FileInfo Nothing type Filename = String -- | Stores File status; Clean means all changes are saved data FileStatus = Dirty | Clean deriving Show instance Default FileStatus where def = Clean -- | Returns 'FileStatus' of current buffer getFileStatus :: BufAction FileStatus getFileStatus = getBufExt -- | Sets 'FileStatus' of current buffer setFileStatus :: FileStatus -> BufAction () setFileStatus = setBufExt -- | Gets filename of current buffer getFilename :: BufAction (Maybe Filename) getFilename = do FileInfo filename <- getBufExt return filename -- | Main export, use this in your Rasa config files :: App () files = do onEveryNewBuffer_ $ do void . onBufTextChanged $ bufferChanged void . addTopStatus $ fileStatus void . addTopStatus $ (fmap Y.fromString <$> getFilename) afterInit $ do loadFiles addCmd "save" $ focusDo_ . saveAs -- | Renders the current file status fileStatus :: BufAction (Maybe RenderInfo) fileStatus = do hasFilename <- isJust <$> getFilename status <- getFileStatus if hasFilename then return . Just $ case status of Dirty -> styleText "✘" $ fg Red Clean -> styleText "✓" $ fg Green else return Nothing -- | Keeps track of buffer status bufferChanged :: BufTextChanged -> BufAction () bufferChanged _ = setFileStatus Dirty saveAs :: String -> BufAction () saveAs fName = getText >>= liftIO . TIO.writeFile fName . Y.toText -- | Save the buffer if we have a filename save :: BufAction () save = do FileInfo mName <- getBufExt case mName of Just fName -> saveAs fName Nothing -> return () setFileStatus Clean -- | Set the filename setFilename :: String -> BufAction () setFilename fname = setBufExt $ FileInfo (Just fname) -- | Add a buffer for a file addFile :: String -> Y.YiString -> App () addFile fname txt = do newBuf <- addBuffer txt bufDo_ newBuf (setFilename fname) -- | Load files from command line loadFiles :: App () loadFiles = do fileNames <- liftIO getArgs fileTexts <- liftIO $ traverse TIO.readFile fileNames mapM_ (uncurry addFile) $ zip fileNames (Y.fromText <$> fileTexts)