{-# LANGUAGE OverloadedStrings #-}

module Cornelis.Config where

import           Cornelis.Types
import           Cornelis.Utils (objectToInt, objectToText)
import           Data.Maybe (fromMaybe)
import qualified Data.Text as T
import           Neovim
import           Neovim.API.Text
import           Control.Monad ((<=<))


------------------------------------------------------------------------------
-- | Attempt to get a variable from vim.
getVar :: Text -> Neovim env (Maybe Object)
getVar :: forall env. Text -> Neovim env (Maybe Object)
getVar Text
v
  = Neovim env (Maybe Object)
-> (NeovimException -> Neovim env (Maybe Object))
-> Neovim env (Maybe Object)
forall (io :: * -> *) a.
MonadUnliftIO io =>
io a -> (NeovimException -> io a) -> io a
catchNeovimException (Object -> Maybe Object
forall a. a -> Maybe a
Just (Object -> Maybe Object)
-> Neovim env Object -> Neovim env (Maybe Object)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Neovim env Object
forall env. Text -> Neovim env Object
vim_get_var Text
v)
  ((NeovimException -> Neovim env (Maybe Object))
 -> Neovim env (Maybe Object))
-> (NeovimException -> Neovim env (Maybe Object))
-> Neovim env (Maybe Object)
forall a b. (a -> b) -> a -> b
$ Neovim env (Maybe Object)
-> NeovimException -> Neovim env (Maybe Object)
forall a b. a -> b -> a
const
  (Neovim env (Maybe Object)
 -> NeovimException -> Neovim env (Maybe Object))
-> Neovim env (Maybe Object)
-> NeovimException
-> Neovim env (Maybe Object)
forall a b. (a -> b) -> a -> b
$ Maybe Object -> Neovim env (Maybe Object)
forall a. a -> Neovim env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Object
forall a. Maybe a
Nothing


------------------------------------------------------------------------------
-- | Get the first variable from vim that succeeds. Useful for variable names
-- that have changed over time.
getVarWithAlternatives :: [Text] -> Neovim env (Maybe Object)
getVarWithAlternatives :: forall env. [Text] -> Neovim env (Maybe Object)
getVarWithAlternatives = (First Object -> Maybe Object)
-> Neovim env (First Object) -> Neovim env (Maybe Object)
forall a b. (a -> b) -> Neovim env a -> Neovim env b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap First Object -> Maybe Object
forall a. First a -> Maybe a
getFirst (Neovim env (First Object) -> Neovim env (Maybe Object))
-> ([Text] -> Neovim env (First Object))
-> [Text]
-> Neovim env (Maybe Object)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Neovim env (First Object))
-> [Text] -> Neovim env (First Object)
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Maybe Object -> First Object)
-> Neovim env (Maybe Object) -> Neovim env (First Object)
forall a b. (a -> b) -> Neovim env a -> Neovim env b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe Object -> First Object
forall a. Maybe a -> First a
First (Neovim env (Maybe Object) -> Neovim env (First Object))
-> (Text -> Neovim env (Maybe Object))
-> Text
-> Neovim env (First Object)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Neovim env (Maybe Object)
forall env. Text -> Neovim env (Maybe Object)
getVar)


------------------------------------------------------------------------------
-- | Build a 'CornelisConfig' from .vimrc
getConfig :: Neovim env CornelisConfig
getConfig :: forall env. Neovim env CornelisConfig
getConfig
  = Int64 -> Int64 -> SplitLocation -> CornelisConfig
CornelisConfig
    (Int64 -> Int64 -> SplitLocation -> CornelisConfig)
-> Neovim env Int64
-> Neovim env (Int64 -> SplitLocation -> CornelisConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Maybe Object -> Int64)
-> Neovim env (Maybe Object) -> Neovim env Int64
forall a b. (a -> b) -> Neovim env a -> Neovim env b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int64 -> Maybe Int64 -> Int64
forall a. a -> Maybe a -> a
fromMaybe Int64
31 (Maybe Int64 -> Int64)
-> (Maybe Object -> Maybe Int64) -> Maybe Object -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Object -> Maybe Int64
forall a. Num a => Object -> Maybe a
objectToInt =<<))
        (Text -> Neovim env (Maybe Object)
forall env. Text -> Neovim env (Maybe Object)
getVar Text
"cornelis_max_size")
    Neovim env (Int64 -> SplitLocation -> CornelisConfig)
-> Neovim env Int64 -> Neovim env (SplitLocation -> CornelisConfig)
forall a b. Neovim env (a -> b) -> Neovim env a -> Neovim env b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Maybe Object -> Int64)
-> Neovim env (Maybe Object) -> Neovim env Int64
forall a b. (a -> b) -> Neovim env a -> Neovim env b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int64 -> Maybe Int64 -> Int64
forall a. a -> Maybe a -> a
fromMaybe Int64
31 (Maybe Int64 -> Int64)
-> (Maybe Object -> Maybe Int64) -> Maybe Object -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Object -> Maybe Int64
forall a. Num a => Object -> Maybe a
objectToInt =<<))
        (Text -> Neovim env (Maybe Object)
forall env. Text -> Neovim env (Maybe Object)
getVar Text
"cornelis_max_width")
    Neovim env (SplitLocation -> CornelisConfig)
-> Neovim env SplitLocation -> Neovim env CornelisConfig
forall a b. Neovim env (a -> b) -> Neovim env a -> Neovim env b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (SplitLocation -> Maybe SplitLocation -> SplitLocation
forall a. a -> Maybe a -> a
fromMaybe SplitLocation
Horizontal (Maybe SplitLocation -> SplitLocation)
-> (Maybe Object -> Maybe SplitLocation)
-> Maybe Object
-> SplitLocation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Object
-> (Object -> Maybe SplitLocation) -> Maybe SplitLocation
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> Maybe SplitLocation
readSplitLocation (String -> Maybe SplitLocation)
-> (Text -> String) -> Text -> Maybe SplitLocation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> Maybe SplitLocation)
-> (Object -> Maybe Text) -> Object -> Maybe SplitLocation
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Object -> Maybe Text
objectToText)) (Maybe Object -> SplitLocation)
-> Neovim env (Maybe Object) -> Neovim env SplitLocation
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        [Text] -> Neovim env (Maybe Object)
forall env. [Text] -> Neovim env (Maybe Object)
getVarWithAlternatives [Text
"cornelis_split_location", Text
"cornelis_split_direction"])