zwirn-0.2.3.1: app/zwirnmill/Editor/File.hs
module Editor.File where
import Brick hiding (on)
import Brick.BChan (writeBChan)
import Control.Concurrent (forkIO)
import Control.Monad (void)
import Control.Monad.IO.Class (liftIO)
import qualified Data.Base64.Types as B64
import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as B64
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import qualified Data.Text.Zipper as Z
import Editor.Core
import Editor.Selection
import Editor.Util
import Graphics.UI.TinyFileDialogs (openFileDialog, saveFileDialog)
import qualified Graphics.Vty as V
import Lens.Micro
import Lens.Micro.Extras
import UI.Core
saveEvent :: EventM Name EditorEventEnv ()
saveEvent = do
result <- gets (view envEditorState) >>= liftIO . saveFile
case result of
Right es' -> modify $ envEditorState .~ es'
Left msg -> modify $ envEditorState %~ setMessage msg
openEvent :: EventM Name EditorEventEnv ()
openEvent = do
chan <- gets (view envBChan)
void $ liftIO $ forkIO $ do
mPath <- openFile
writeBChan chan (FileSelected mPath)
copyEvent :: EventM Name EditorEventEnv ()
copyEvent = do
es <- gets (view envEditorState)
vtyOut <- gets (view envVtyOut)
case selectedText es of
Nothing -> return ()
Just t -> case vtyOut of
Nothing -> return ()
Just out -> do
liftIO (copyToClipboard out t)
modify $ envEditorState %~ setMessage "Copied."
loadEvent :: FilePath -> EventM Name EditorEventEnv ()
loadEvent path = do
contents <- liftIO (readFile path)
modify $ envEditorState .~ loadFile path (T.pack contents)
saveFile :: EditorState -> IO (Either String EditorState)
saveFile es =
case es ^. esFilePath of
Nothing -> do
mpath <- saveFileDialog "save file" "untitled.zwirn" ["*.zwirn"] "zwirn files"
case mpath of
Nothing -> return $ Left "Failed to get path"
Just path -> do
writeFile (T.unpack path) (T.unpack content)
return $
Right $
es
& esUnsaved .~ False
& esMessage ?~ "Saved."
& esFilePath ?~ T.unpack path
Just path -> do
writeFile path (T.unpack content)
return $ Right $ es & esUnsaved .~ False & esMessage ?~ "Saved."
where
content = getContent es
loadFile :: FilePath -> Text -> EditorState
loadFile path contents =
let ls = T.lines contents
in newEditor
& esZipper .~ Z.textZipper ls Nothing
& esFilePath ?~ path
& esUnsaved .~ False
openFile :: IO (Maybe FilePath)
openFile = fmap T.unpack . safeHead <$> openFileDialog "choose a zwirn file" "untitled.zwirn" ["*.zwirn"] "zwirn files" False
where
safeHead (Just (x : _)) = Just x
safeHead _ = Nothing
copyToClipboard :: V.Output -> Text -> IO ()
copyToClipboard output text = V.outputByteBuffer output osc52
where
textBytes = TE.encodeUtf8 text
b64Bytes = B64.extractBase64 $ B64.encodeBase64' textBytes
osc52 = B.concat ["\ESC]52;c;", b64Bytes, "\BEL"]