yi-rope 0.6.0.0 → 0.7.0.0
raw patch · 2 files changed
+37/−9 lines, 2 files
Files
- src/Yi/Rope.hs +36/−8
- yi-rope.cabal +1/−1
src/Yi/Rope.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_HADDOCK show-extensions #-} -- |@@ -75,6 +76,7 @@ import Data.Monoid import Data.String (IsString(..)) import qualified Data.Text as TX+import qualified Data.Text.Encoding as TXE import Data.Text.ICU.Convert import qualified Data.Text.IO as TF (writeFile) import Data.Typeable@@ -669,15 +671,27 @@ -- brand new file, you can use 'writeFileUsingText'. -- -- It's up to the user to handle exceptions.-writeFile :: FilePath -> YiString -> ConverterName -> IO ()+--+-- Returns an error message if conversion failed, otherwise Nothing+-- on success.+writeFile :: FilePath -> YiString -> ConverterName -> IO (Maybe TX.Text) writeFile f s (CN cn) = open cn (Just True) >>= writeFileWithConverter f s -- | As 'writeFile' but using the provided 'Converter' rather than -- creating one from a 'ConverterName'. -- -- It's up to the user to handle exceptions.-writeFileWithConverter :: FilePath -> YiString -> Converter -> IO ()-writeFileWithConverter f s c = BS.writeFile f (fromUnicode c $ toText s)+writeFileWithConverter :: FilePath -> YiString -> Converter -> IO (Maybe TX.Text)+writeFileWithConverter f s c = do+ let bytes = fromUnicode c $ toText s+ errorMsg = "Could not encode text with specified encoding"+ enc <- detectEncoding errorMsg $ BSL.fromChunks [bytes]+ case enc of+ Left err -> return $ Just err+ Right (_, (CN cn)) -> do+ if cn == getName c+ then BS.writeFile f bytes >> return Nothing+ else return . Just $ errorMsg -- | Write a 'YiString' into the given file. This function uses -- 'TF.writeFile' to do the writing: if you have special needs for@@ -698,15 +712,29 @@ -- It is up to the user to handle exceptions not directly related to -- character decoding. readFile :: FilePath -> IO (Either TX.Text (YiString, ConverterName))-readFile fp = do- cs <- BSL.readFile fp+readFile fp = BSL.readFile fp >>= detectEncoding err+ where err = "Could not guess the encoding of " <> TX.pack fp++-- | Detects the encoding of a sequence of bytes.+--+-- Presumably the calculating the 'YiString' is lazy so it is fine+-- to use this to only get the converter name.+--+-- Also allows specification of the error to return if the encoding+-- of the bytes cannot be detected. The error returns won't necessarily+-- be this error - it is used only if no encoding name is detected at all.+detectEncoding :: TX.Text -> BSL.ByteString+ -> IO (Either TX.Text (YiString, ConverterName))+detectEncoding err cs = case detectEncodingName cs of- Nothing -> return . Left . TX.pack $ "Could not guess the encoding of " <> fp+ Nothing -> return $ case TXE.decodeUtf8' $ BSL.toStrict cs of+ -- The detection failed but stay optimistic and try as UTF8 anyway.+ Left _ -> Left err+ Right tx -> Right (fromText tx, CN "UTF-8") Just enc -> do let ke = if enc == "ASCII" then Just "UTF-8" else listToMaybe $ aliases enc case ke of- Nothing -> return . Left . TX.pack $- "Don't know how to decode as " <> enc+ Nothing -> return . Left . TX.pack $ "Don't know how to decode as " <> enc Just s -> do c <- open s (Just True) let st = BSL.toStrict cs
yi-rope.cabal view
@@ -1,5 +1,5 @@ name: yi-rope-version: 0.6.0.0+version: 0.7.0.0 synopsis: A rope data structure used by Yi description: A rope data structure used by Yi license: GPL-2