module System.Console.Haskeline.History(
History(),
emptyHistory,
addHistory,
historyLines,
readHistory,
writeHistory,
stifleHistory,
stifleAmount,
) where
import qualified Data.Sequence as Seq
import Data.Foldable
import qualified Data.ByteString as B
import qualified Data.ByteString.UTF8 as UTF8
import Control.Exception.Extensible
import System.Directory(doesFileExist)
data History = History {histLines :: Seq.Seq String,
stifleAmt :: Maybe Int}
stifleAmount :: History -> Maybe Int
stifleAmount = stifleAmt
instance Show History where
show = show . histLines
emptyHistory :: History
emptyHistory = History Seq.empty Nothing
historyLines :: History -> [String]
historyLines = toList . histLines
readHistory :: FilePath -> IO History
readHistory file = handle (\(_::IOException) -> return emptyHistory) $ do
exists <- doesFileExist file
contents <- if exists
then fmap UTF8.toString (B.readFile file)
else return ""
evaluate (length contents)
return $ History {histLines = Seq.fromList $ lines contents,
stifleAmt = Nothing}
writeHistory :: FilePath -> History -> IO ()
writeHistory file = handle (\(_::IOException) -> return ())
. B.writeFile file . UTF8.fromString
. unlines . historyLines
stifleHistory :: Maybe Int -> History -> History
stifleHistory Nothing hist = hist {stifleAmt = Nothing}
stifleHistory a@(Just n) hist = History {histLines = stifleFnc (histLines hist),
stifleAmt = a}
where
stifleFnc = if n > Seq.length (histLines hist)
then id
else Seq.fromList . take n . toList
addHistory :: String -> History -> History
addHistory s h = h {histLines = s Seq.<| stifledLines}
where
stifledLines = if maybe True (> Seq.length (histLines h)) (stifleAmt h)
then histLines h
else case Seq.viewr (histLines h) of
Seq.EmptyR -> histLines h
ls Seq.:> _ -> ls