{-# LANGUAGE LambdaCase #-}
{- |
Module      :  Neovim.User.Input
Description :  Utility functions to retrieve user input
Copyright   :  (c) Sebastian Witte
License     :  Apache-2.0

Maintainer  :  woozletoff@gmail.com
Stability   :  experimental
Portability :  GHC

-}
module Neovim.User.Input
    where

import Neovim
import Neovim.API.String
import Neovim.User.Choice

import System.Directory


-- | Helper function that calls the @input()@ function of neovim.
input :: NvimObject result
      => String -- ^ Message to display
      -> Maybe String -- ^ Input fiiled in
      -> Maybe String -- ^ Completion mode
      -> Neovim env result
input :: String -> Maybe String -> Maybe String -> Neovim env result
input String
message Maybe String
mPrefilled Maybe String
mCompletion = (Object -> result) -> Neovim env Object -> Neovim env result
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Object -> result
forall o. NvimObject o => Object -> o
fromObjectUnsafe
  (Neovim env Object -> Neovim env result)
-> Neovim env Object -> Neovim env result
forall a b. (a -> b) -> a -> b
$ String -> [Object] -> forall env. Neovim env Object
vim_call_function String
"input" ([Object] -> forall env. Neovim env Object)
-> [Object] -> forall env. Neovim env Object
forall a b. (a -> b) -> a -> b
$ (String
message String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" ")
    String -> [Object] -> [Object]
forall o. NvimObject o => o -> [Object] -> [Object]
+: String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" String -> String
forall a. a -> a
id Maybe String
mPrefilled
    String -> [Object] -> [Object]
forall o. NvimObject o => o -> [Object] -> [Object]
+: [Object] -> (String -> [Object]) -> Maybe String -> [Object]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (String -> [Object] -> [Object]
forall o. NvimObject o => o -> [Object] -> [Object]
+: []) Maybe String
mCompletion


-- | Prompt the user to specify a directory.
--
-- If the directory does not exist, ask the usere whether it should be created.
askForDirectory :: String -- ^ Message to put in front
                -> Maybe FilePath -- ^ Prefilled text
                -> Neovim env FilePath
askForDirectory :: String -> Maybe String -> Neovim env String
askForDirectory String
message Maybe String
mPrefilled = do
    String
fp <- String -> Maybe String -> Maybe String -> Neovim env String
forall result env.
NvimObject result =>
String -> Maybe String -> Maybe String -> Neovim env result
input String
message Maybe String
mPrefilled (String -> Maybe String
forall a. a -> Maybe a
Just String
"dir")

    String
efp <- (Object -> String) -> Neovim env Object -> Neovim env String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Object -> String
forall o. NvimObject o => Object -> o
fromObjectUnsafe (Neovim env Object -> Neovim env String)
-> Neovim env Object -> Neovim env String
forall a b. (a -> b) -> a -> b
$ String -> [Object] -> forall env. Neovim env Object
vim_call_function String
"expand" ([Object] -> forall env. Neovim env Object)
-> [Object] -> forall env. Neovim env Object
forall a b. (a -> b) -> a -> b
$ (String
fp :: FilePath) String -> [Object] -> [Object]
forall o. NvimObject o => o -> [Object] -> [Object]
+: []

    Neovim env Bool -> Neovim env () -> Neovim env ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (Bool -> Bool
not (Bool -> Bool) -> Neovim env Bool -> Neovim env Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Bool -> Neovim env Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO Bool
doesDirectoryExist String
efp)) (Neovim env () -> Neovim env ()) -> Neovim env () -> Neovim env ()
forall a b. (a -> b) -> a -> b
$
        Neovim env Bool -> Neovim env () -> Neovim env ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (String -> Neovim env Bool
forall env. String -> Neovim env Bool
yesOrNo (String
efp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" does not exist, create it?")) (Neovim env () -> Neovim env ()) -> Neovim env () -> Neovim env ()
forall a b. (a -> b) -> a -> b
$
            IO () -> Neovim env ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Neovim env ()) -> IO () -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ Bool -> String -> IO ()
createDirectoryIfMissing Bool
True String
efp

    String -> Neovim env String
forall (m :: * -> *) a. Monad m => a -> m a
return String
efp


askForString :: String -- ^ message to put in front
             -> Maybe String -- ^ Prefilled text
             -> Neovim env String
askForString :: String -> Maybe String -> Neovim env String
askForString String
message Maybe String
mPrefilled = String -> Maybe String -> Maybe String -> Neovim env String
forall result env.
NvimObject result =>
String -> Maybe String -> Maybe String -> Neovim env result
input String
message Maybe String
mPrefilled Maybe String
forall a. Maybe a
Nothing