-- | Unlifted versions of all FFI methods.
module Linenoise.Unlift
  ( InputResult (..)
  , addHistory
  , clearScreen
  , getInputLine
  , historyLoad
  , historySave
  , printKeycodes
  , setCompletion
  , setMultiline
  , stifleHistory
  )
where

import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.IO.Unlift (MonadUnliftIO, withRunInIO)
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import Linenoise.FFI (InputResult (..))
import qualified Linenoise.FFI as FFI

-- | Add to current history.
addHistory :: MonadIO m => Text -> m ()
addHistory :: forall (m :: * -> *). MonadIO m => Text -> m ()
addHistory = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Text -> IO ()) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> IO ()
FFI.addHistory (ByteString -> IO ()) -> (Text -> ByteString) -> Text -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8

-- | Clear the screen.
clearScreen :: MonadIO m => m ()
clearScreen :: forall (m :: * -> *). MonadIO m => m ()
clearScreen = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ()
FFI.clearScreen

-- | Run the prompt, yielding a string.
getInputLine :: MonadIO m => Text -> m (InputResult Text)
getInputLine :: forall (m :: * -> *). MonadIO m => Text -> m (InputResult Text)
getInputLine = IO (InputResult Text) -> m (InputResult Text)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (InputResult Text) -> m (InputResult Text))
-> (Text -> IO (InputResult Text)) -> Text -> m (InputResult Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InputResult ByteString -> InputResult Text)
-> IO (InputResult ByteString) -> IO (InputResult Text)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ByteString -> Text) -> InputResult ByteString -> InputResult Text
forall a b. (a -> b) -> InputResult a -> InputResult b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
decodeUtf8) (IO (InputResult ByteString) -> IO (InputResult Text))
-> (Text -> IO (InputResult ByteString))
-> Text
-> IO (InputResult Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> IO (InputResult ByteString)
FFI.getInputLine (ByteString -> IO (InputResult ByteString))
-> (Text -> ByteString) -> Text -> IO (InputResult ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8

-- | Load history from a file.
historyLoad :: MonadIO m => FilePath -> m ()
historyLoad :: forall (m :: * -> *). MonadIO m => FilePath -> m ()
historyLoad = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (FilePath -> IO ()) -> FilePath -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO ()
FFI.historyLoad

-- | Save history to a file.
historySave :: MonadIO m => FilePath -> m ()
historySave :: forall (m :: * -> *). MonadIO m => FilePath -> m ()
historySave = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (FilePath -> IO ()) -> FilePath -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO ()
FFI.historySave

-- | Print keycodes.
printKeycodes :: MonadIO m => m ()
printKeycodes :: forall (m :: * -> *). MonadIO m => m ()
printKeycodes = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ()
FFI.printKeycodes

-- | Set the current completion function.
setCompletion :: MonadUnliftIO m => (Text -> m [Text]) -> m ()
setCompletion :: forall (m :: * -> *). MonadUnliftIO m => (Text -> m [Text]) -> m ()
setCompletion Text -> m [Text]
f =
  let g :: ByteString -> m [ByteString]
g = ([Text] -> [ByteString]) -> m [Text] -> m [ByteString]
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Text -> ByteString) -> [Text] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> ByteString
encodeUtf8) (m [Text] -> m [ByteString])
-> (ByteString -> m [Text]) -> ByteString -> m [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> m [Text]
f (Text -> m [Text])
-> (ByteString -> Text) -> ByteString -> m [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decodeUtf8
  in  ((forall a. m a -> IO a) -> IO ()) -> m ()
forall b. ((forall a. m a -> IO a) -> IO b) -> m b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (\forall a. m a -> IO a
runInIO -> (ByteString -> IO [ByteString]) -> IO ()
FFI.setCompletion (m [ByteString] -> IO [ByteString]
forall a. m a -> IO a
runInIO (m [ByteString] -> IO [ByteString])
-> (ByteString -> m [ByteString]) -> ByteString -> IO [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> m [ByteString]
g))

-- | Enable/Disable multiline input.
setMultiline :: MonadIO m => Bool -> m ()
setMultiline :: forall (m :: * -> *). MonadIO m => Bool -> m ()
setMultiline = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Bool -> IO ()) -> Bool -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> IO ()
FFI.setMultiline

-- | Limit the maximum history length.
stifleHistory :: MonadIO m => Int -> m ()
stifleHistory :: forall (m :: * -> *). MonadIO m => Int -> m ()
stifleHistory = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Int -> IO ()) -> Int -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IO ()
FFI.stifleHistory