{-# LANGUAGE OverloadedStrings #-}

module Cornelis.InfoWin (closeInfoWindows, showInfoWindow, buildInfoBuffer) where

import           Prelude hiding (Left, Right)
import           Control.Monad (unless)
import           Control.Monad.State.Class
import           Cornelis.Pretty
import           Cornelis.Types
import           Cornelis.Utils (withBufferStuff, windowsForBuffer, savingCurrentWindow, visibleBuffers)
import           Data.Foldable (for_)
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Text as T
import           Data.Traversable (for)
import qualified Data.Vector as V
import           Neovim
import           Neovim.API.Text
import           Prettyprinter (layoutPretty, LayoutOptions (LayoutOptions), PageWidth (AvailablePerLine))
import           Prettyprinter.Render.Text (renderStrict)


cornelisWindowVar :: Text
cornelisWindowVar :: Text
cornelisWindowVar = Text
"cornelis_window"

getBufferVariableOfWindow :: NvimObject o => Text -> Window -> Neovim env (Maybe o)
getBufferVariableOfWindow :: forall o env.
NvimObject o =>
Text -> Window -> Neovim env (Maybe o)
getBufferVariableOfWindow Text
variableName Window
window = do
  Window -> Neovim env Bool
forall env. Window -> Neovim env Bool
window_is_valid Window
window Neovim env Bool
-> (Bool -> Neovim env (Maybe o)) -> Neovim env (Maybe o)
forall a b. Neovim env a -> (a -> Neovim env b) -> Neovim env b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Bool
False -> Maybe o -> Neovim env (Maybe o)
forall a. a -> Neovim env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe o
forall a. Maybe a
Nothing
    Bool
True -> do
      Buffer
buffer <- Window -> Neovim env Buffer
forall env. Window -> Neovim env Buffer
window_get_buffer Window
window
      let getVariableValue :: Neovim env (Maybe o)
getVariableValue = o -> Maybe o
forall a. a -> Maybe a
Just (o -> Maybe o) -> (Object -> o) -> Object -> Maybe o
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Object -> o
forall o. NvimObject o => Object -> o
fromObjectUnsafe (Object -> Maybe o) -> Neovim env Object -> Neovim env (Maybe o)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Buffer -> Text -> Neovim env Object
forall env. Buffer -> Text -> Neovim env Object
buffer_get_var Buffer
buffer Text
variableName
      Neovim env (Maybe o)
forall {env}. Neovim env (Maybe o)
getVariableValue Neovim env (Maybe o)
-> (NeovimException -> Neovim env (Maybe o))
-> Neovim env (Maybe o)
forall (io :: * -> *) a.
MonadUnliftIO io =>
io a -> (NeovimException -> io a) -> io a
`catchNeovimException` Neovim env (Maybe o) -> NeovimException -> Neovim env (Maybe o)
forall a b. a -> b -> a
const (Maybe o -> Neovim env (Maybe o)
forall a. a -> Neovim env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe o
forall a. Maybe a
Nothing)

closeInfoWindowsForUnseenBuffers :: Neovim CornelisEnv ()
closeInfoWindowsForUnseenBuffers :: Neovim CornelisEnv ()
closeInfoWindowsForUnseenBuffers = do
  Set Buffer
seen <- [Buffer] -> Set Buffer
forall a. Ord a => [a] -> Set a
S.fromList ([Buffer] -> Set Buffer)
-> ([(Window, Buffer)] -> [Buffer])
-> [(Window, Buffer)]
-> Set Buffer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Window, Buffer) -> Buffer) -> [(Window, Buffer)] -> [Buffer]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Window, Buffer) -> Buffer
forall a b. (a, b) -> b
snd ([(Window, Buffer)] -> Set Buffer)
-> Neovim CornelisEnv [(Window, Buffer)]
-> Neovim CornelisEnv (Set Buffer)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Neovim CornelisEnv [(Window, Buffer)]
forall env. Neovim env [(Window, Buffer)]
visibleBuffers
  Map Buffer BufferStuff
bufs <- (CornelisState -> Map Buffer BufferStuff)
-> Neovim CornelisEnv (Map Buffer BufferStuff)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets CornelisState -> Map Buffer BufferStuff
cs_buffers
  let known :: Set Buffer
known = Map Buffer BufferStuff -> Set Buffer
forall k a. Map k a -> Set k
M.keysSet Map Buffer BufferStuff
bufs
      unseen :: Set Buffer
unseen = Set Buffer
known Set Buffer -> Set Buffer -> Set Buffer
forall a. Ord a => Set a -> Set a -> Set a
S.\\ Set Buffer
seen
  Set Buffer
-> (Buffer -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set Buffer
unseen ((Buffer -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ())
-> (Buffer -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ \Buffer
b -> do
    Maybe BufferStuff
-> (BufferStuff -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Buffer -> Map Buffer BufferStuff -> Maybe BufferStuff
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Buffer
b Map Buffer BufferStuff
bufs) ((BufferStuff -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ())
-> (BufferStuff -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ \BufferStuff
bs -> do
      [Window]
ws <- Buffer -> Neovim CornelisEnv [Window]
forall env. Buffer -> Neovim env [Window]
windowsForBuffer (Buffer -> Neovim CornelisEnv [Window])
-> Buffer -> Neovim CornelisEnv [Window]
forall a b. (a -> b) -> a -> b
$ InfoBuffer -> Buffer
iw_buffer (InfoBuffer -> Buffer) -> InfoBuffer -> Buffer
forall a b. (a -> b) -> a -> b
$ BufferStuff -> InfoBuffer
bs_info_win BufferStuff
bs
      [Window]
-> (Window -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Window]
ws ((Window -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ())
-> (Window -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ (Window -> Bool -> Neovim CornelisEnv ())
-> Bool -> Window -> Neovim CornelisEnv ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Window -> Bool -> Neovim CornelisEnv ()
forall env. Window -> Bool -> Neovim env ()
nvim_win_close Bool
True

closeInfoWindows :: Neovim env ()
closeInfoWindows :: forall env. Neovim env ()
closeInfoWindows = do
  Vector Window
ws <- Neovim env (Vector Window)
forall env. Neovim env (Vector Window)
vim_get_windows
  Vector Window -> (Window -> Neovim env ()) -> Neovim env ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Vector Window
ws ((Window -> Neovim env ()) -> Neovim env ())
-> (Window -> Neovim env ()) -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ \Window
w -> Text -> Window -> Neovim env (Maybe Bool)
forall o env.
NvimObject o =>
Text -> Window -> Neovim env (Maybe o)
getBufferVariableOfWindow Text
cornelisWindowVar Window
w Neovim env (Maybe Bool)
-> (Maybe Bool -> Neovim env ()) -> Neovim env ()
forall a b. Neovim env a -> (a -> Neovim env b) -> Neovim env b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Just Bool
True -> Window -> Bool -> Neovim env ()
forall env. Window -> Bool -> Neovim env ()
nvim_win_close Window
w Bool
True
    Maybe Bool
_ -> () -> Neovim env ()
forall a. a -> Neovim env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()


closeInfoWindowForBuffer :: BufferStuff -> Neovim CornelisEnv ()
closeInfoWindowForBuffer :: BufferStuff -> Neovim CornelisEnv ()
closeInfoWindowForBuffer BufferStuff
bs = do
  let InfoBuffer Buffer
ib = BufferStuff -> InfoBuffer
bs_info_win BufferStuff
bs
  [Window]
ws <- Buffer -> Neovim CornelisEnv [Window]
forall env. Buffer -> Neovim env [Window]
windowsForBuffer Buffer
ib
  [Window]
-> (Window -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Window]
ws ((Window -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ())
-> (Window -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ (Window -> Bool -> Neovim CornelisEnv ())
-> Bool -> Window -> Neovim CornelisEnv ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Window -> Bool -> Neovim CornelisEnv ()
forall env. Window -> Bool -> Neovim env ()
nvim_win_close Bool
True



showInfoWindow :: Buffer -> Doc HighlightGroup -> Neovim CornelisEnv ()
showInfoWindow :: Buffer -> Doc HighlightGroup -> Neovim CornelisEnv ()
showInfoWindow Buffer
b Doc HighlightGroup
doc = Buffer
-> (BufferStuff -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall a.
Monoid a =>
Buffer
-> (BufferStuff -> Neovim CornelisEnv a) -> Neovim CornelisEnv a
withBufferStuff Buffer
b ((BufferStuff -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ())
-> (BufferStuff -> Neovim CornelisEnv ()) -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ \BufferStuff
bs -> do
  let ib :: InfoBuffer
ib = BufferStuff -> InfoBuffer
bs_info_win BufferStuff
bs
  Neovim CornelisEnv ()
closeInfoWindowsForUnseenBuffers

  [(Window, Buffer)]
vis <- Neovim CornelisEnv [(Window, Buffer)]
forall env. Neovim env [(Window, Buffer)]
visibleBuffers
  Int64
ns <- (CornelisEnv -> Int64) -> Neovim CornelisEnv Int64
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks CornelisEnv -> Int64
ce_namespace

  -- Check if the info win still exists, and if so, just modify it
  Bool
found <- ([Bool] -> Bool)
-> Neovim CornelisEnv [Bool] -> Neovim CornelisEnv Bool
forall a b.
(a -> b) -> Neovim CornelisEnv a -> Neovim CornelisEnv b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or (Neovim CornelisEnv [Bool] -> Neovim CornelisEnv Bool)
-> Neovim CornelisEnv [Bool] -> Neovim CornelisEnv Bool
forall a b. (a -> b) -> a -> b
$
    [(Window, Buffer)]
-> ((Window, Buffer) -> Neovim CornelisEnv Bool)
-> Neovim CornelisEnv [Bool]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(Window, Buffer)]
vis (((Window, Buffer) -> Neovim CornelisEnv Bool)
 -> Neovim CornelisEnv [Bool])
-> ((Window, Buffer) -> Neovim CornelisEnv Bool)
-> Neovim CornelisEnv [Bool]
forall a b. (a -> b) -> a -> b
$ \(Window
w, Buffer
vb) -> do
      case Buffer
vb Buffer -> Buffer -> Bool
forall a. Eq a => a -> a -> Bool
== InfoBuffer -> Buffer
iw_buffer InfoBuffer
ib of
        Bool
False -> Bool -> Neovim CornelisEnv Bool
forall a. a -> Neovim CornelisEnv a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
        Bool
True -> do
          Int64 -> InfoBuffer -> Doc HighlightGroup -> Neovim CornelisEnv ()
forall env.
Int64 -> InfoBuffer -> Doc HighlightGroup -> Neovim env ()
writeInfoBuffer Int64
ns InfoBuffer
ib Doc HighlightGroup
doc
          Window -> InfoBuffer -> Neovim CornelisEnv ()
resizeInfoWin Window
w InfoBuffer
ib
          Bool -> Neovim CornelisEnv Bool
forall a. a -> Neovim CornelisEnv a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True

  -- Otherwise we need to rebuild it
  Bool -> Neovim CornelisEnv () -> Neovim CornelisEnv ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
found (Neovim CornelisEnv () -> Neovim CornelisEnv ())
-> Neovim CornelisEnv () -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ do
    BufferStuff -> Neovim CornelisEnv ()
closeInfoWindowForBuffer BufferStuff
bs
    Int64 -> InfoBuffer -> Doc HighlightGroup -> Neovim CornelisEnv ()
forall env.
Int64 -> InfoBuffer -> Doc HighlightGroup -> Neovim env ()
writeInfoBuffer Int64
ns InfoBuffer
ib Doc HighlightGroup
doc
    [Window]
ws <- Buffer -> Neovim CornelisEnv [Window]
forall env. Buffer -> Neovim env [Window]
windowsForBuffer Buffer
b
    [Window]
-> (Window -> Neovim CornelisEnv Window) -> Neovim CornelisEnv ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Window]
ws ((Window -> Neovim CornelisEnv Window) -> Neovim CornelisEnv ())
-> (Window -> Neovim CornelisEnv Window) -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ InfoBuffer -> Window -> Neovim CornelisEnv Window
buildInfoWindow InfoBuffer
ib



buildInfoBuffer :: Neovim env InfoBuffer
buildInfoBuffer :: forall env. Neovim env InfoBuffer
buildInfoBuffer = do
  Buffer
b <-
    -- not listed in the buffer list, is throwaway
    Bool -> Bool -> Neovim env Buffer
forall env. Bool -> Bool -> Neovim env Buffer
nvim_create_buf Bool
False Bool
True

  -- Setup things in the buffer
  Neovim env Object -> Neovim env ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Neovim env Object -> Neovim env ())
-> Neovim env Object -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ Buffer -> Text -> Object -> Neovim env Object
forall env. Buffer -> Text -> Object -> Neovim env Object
buffer_set_var Buffer
b Text
cornelisWindowVar (Object -> Neovim env Object) -> Object -> Neovim env Object
forall a b. (a -> b) -> a -> b
$ Bool -> Object
ObjectBool Bool
True
  Buffer -> Text -> Object -> Neovim env ()
forall env. Buffer -> Text -> Object -> Neovim env ()
nvim_buf_set_option Buffer
b Text
"modifiable" (Object -> Neovim env ()) -> Object -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ Bool -> Object
ObjectBool Bool
False
  Buffer -> Text -> Object -> Neovim env ()
forall env. Buffer -> Text -> Object -> Neovim env ()
nvim_buf_set_option Buffer
b Text
"filetype" (Object -> Neovim env ()) -> Object -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Object
ObjectString ByteString
"agdainfo"
  InfoBuffer -> Neovim env InfoBuffer
forall a. a -> Neovim env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (InfoBuffer -> Neovim env InfoBuffer)
-> InfoBuffer -> Neovim env InfoBuffer
forall a b. (a -> b) -> a -> b
$ Buffer -> InfoBuffer
InfoBuffer Buffer
b




buildInfoWindow :: InfoBuffer -> Window -> Neovim CornelisEnv Window
buildInfoWindow :: InfoBuffer -> Window -> Neovim CornelisEnv Window
buildInfoWindow (InfoBuffer Buffer
split_buf) Window
w = Neovim CornelisEnv Window -> Neovim CornelisEnv Window
forall env a. Neovim env a -> Neovim env a
savingCurrentWindow (Neovim CornelisEnv Window -> Neovim CornelisEnv Window)
-> Neovim CornelisEnv Window -> Neovim CornelisEnv Window
forall a b. (a -> b) -> a -> b
$ do
  Window -> Neovim CornelisEnv ()
forall env. Window -> Neovim env ()
nvim_set_current_win Window
w
  Text
max_height <-  (CornelisEnv -> Text) -> Neovim CornelisEnv Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ((CornelisEnv -> Text) -> Neovim CornelisEnv Text)
-> (CornelisEnv -> Text) -> Neovim CornelisEnv Text
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> (CornelisEnv -> String) -> CornelisEnv -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> String
forall a. Show a => a -> String
show (Int64 -> String)
-> (CornelisEnv -> Int64) -> CornelisEnv -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CornelisConfig -> Int64
cc_max_height (CornelisConfig -> Int64)
-> (CornelisEnv -> CornelisConfig) -> CornelisEnv -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CornelisEnv -> CornelisConfig
ce_config
  Text
max_width <- (CornelisEnv -> Text) -> Neovim CornelisEnv Text
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ((CornelisEnv -> Text) -> Neovim CornelisEnv Text)
-> (CornelisEnv -> Text) -> Neovim CornelisEnv Text
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> (CornelisEnv -> String) -> CornelisEnv -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> String
forall a. Show a => a -> String
show (Int64 -> String)
-> (CornelisEnv -> Int64) -> CornelisEnv -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CornelisConfig -> Int64
cc_max_width (CornelisConfig -> Int64)
-> (CornelisEnv -> CornelisConfig) -> CornelisEnv -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CornelisEnv -> CornelisConfig
ce_config
  (CornelisEnv -> SplitLocation) -> Neovim CornelisEnv SplitLocation
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (CornelisConfig -> SplitLocation
cc_split_location (CornelisConfig -> SplitLocation)
-> (CornelisEnv -> CornelisConfig) -> CornelisEnv -> SplitLocation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CornelisEnv -> CornelisConfig
ce_config) Neovim CornelisEnv SplitLocation
-> (SplitLocation -> Neovim CornelisEnv ())
-> Neovim CornelisEnv ()
forall a b.
Neovim CornelisEnv a
-> (a -> Neovim CornelisEnv b) -> Neovim CornelisEnv b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    SplitLocation
Vertical   -> Text -> Neovim CornelisEnv ()
forall env. Text -> Neovim env ()
vim_command (Text -> Neovim CornelisEnv ()) -> Text -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Text
max_width Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" vsplit"
    SplitLocation
Horizontal -> Text -> Neovim CornelisEnv ()
forall env. Text -> Neovim env ()
vim_command (Text -> Neovim CornelisEnv ()) -> Text -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Text
max_height Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" split"
    SplitLocation
OnLeft     -> Text -> Neovim CornelisEnv ()
forall env. Text -> Neovim env ()
vim_command (Text -> Neovim CornelisEnv ()) -> Text -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Text
"topleft " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
max_width Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" vsplit"
    SplitLocation
OnRight    -> Text -> Neovim CornelisEnv ()
forall env. Text -> Neovim env ()
vim_command (Text -> Neovim CornelisEnv ()) -> Text -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Text
"botright " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
max_width Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" vsplit"
    SplitLocation
OnTop      -> Text -> Neovim CornelisEnv ()
forall env. Text -> Neovim env ()
vim_command (Text -> Neovim CornelisEnv ()) -> Text -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Text
"topleft " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
max_height Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" split"
    SplitLocation
OnBottom   -> Text -> Neovim CornelisEnv ()
forall env. Text -> Neovim env ()
vim_command (Text -> Neovim CornelisEnv ()) -> Text -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Text
"botright " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
max_height Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" split"
  Window
split_win <- Neovim CornelisEnv Window
forall env. Neovim env Window
nvim_get_current_win
  Window -> Buffer -> Neovim CornelisEnv ()
forall env. Window -> Buffer -> Neovim env ()
nvim_win_set_buf Window
split_win Buffer
split_buf

  -- Setup things in the window
  Window -> Text -> Object -> Neovim CornelisEnv ()
forall env. Window -> Text -> Object -> Neovim env ()
nvim_win_set_option Window
split_win Text
"relativenumber" (Object -> Neovim CornelisEnv ())
-> Object -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Bool -> Object
ObjectBool Bool
False
  Window -> Text -> Object -> Neovim CornelisEnv ()
forall env. Window -> Text -> Object -> Neovim env ()
nvim_win_set_option Window
split_win Text
"number" (Object -> Neovim CornelisEnv ())
-> Object -> Neovim CornelisEnv ()
forall a b. (a -> b) -> a -> b
$ Bool -> Object
ObjectBool Bool
False

  Window -> InfoBuffer -> Neovim CornelisEnv ()
resizeInfoWin Window
split_win (Buffer -> InfoBuffer
InfoBuffer Buffer
split_buf)

  Window -> Neovim CornelisEnv Window
forall a. a -> Neovim CornelisEnv a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Window
split_win

resizeInfoWin :: Window -> InfoBuffer -> Neovim CornelisEnv ()
resizeInfoWin :: Window -> InfoBuffer -> Neovim CornelisEnv ()
resizeInfoWin Window
w InfoBuffer
ib = do
  Vector Text
t <- Buffer
-> Int64 -> Int64 -> Bool -> Neovim CornelisEnv (Vector Text)
forall env.
Buffer -> Int64 -> Int64 -> Bool -> Neovim env (Vector Text)
nvim_buf_get_lines (InfoBuffer -> Buffer
iw_buffer InfoBuffer
ib) Int64
0 (-Int64
1) Bool
False
  Int64
max_size <- (CornelisEnv -> Int64) -> Neovim CornelisEnv Int64
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ((CornelisEnv -> Int64) -> Neovim CornelisEnv Int64)
-> (CornelisEnv -> Int64) -> Neovim CornelisEnv Int64
forall a b. (a -> b) -> a -> b
$ CornelisConfig -> Int64
cc_max_height (CornelisConfig -> Int64)
-> (CornelisEnv -> CornelisConfig) -> CornelisEnv -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CornelisEnv -> CornelisConfig
ce_config
  let size :: Int64
size = Int64 -> Int64 -> Int64
forall a. Ord a => a -> a -> a
min Int64
max_size (Int64 -> Int64) -> Int64 -> Int64
forall a b. (a -> b) -> a -> b
$ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int64) -> Int -> Int64
forall a b. (a -> b) -> a -> b
$ Vector Text -> Int
forall a. Vector a -> Int
V.length Vector Text
t
  (CornelisEnv -> SplitLocation) -> Neovim CornelisEnv SplitLocation
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (CornelisConfig -> SplitLocation
cc_split_location (CornelisConfig -> SplitLocation)
-> (CornelisEnv -> CornelisConfig) -> CornelisEnv -> SplitLocation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CornelisEnv -> CornelisConfig
ce_config) Neovim CornelisEnv SplitLocation
-> (SplitLocation -> Neovim CornelisEnv ())
-> Neovim CornelisEnv ()
forall a b.
Neovim CornelisEnv a
-> (a -> Neovim CornelisEnv b) -> Neovim CornelisEnv b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    SplitLocation
Vertical   -> () -> Neovim CornelisEnv ()
forall a. a -> Neovim CornelisEnv a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    SplitLocation
Horizontal -> Window -> Int64 -> Neovim CornelisEnv ()
forall env. Window -> Int64 -> Neovim env ()
window_set_height Window
w Int64
size
    SplitLocation
OnLeft     -> () -> Neovim CornelisEnv ()
forall a. a -> Neovim CornelisEnv a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    SplitLocation
OnRight    -> () -> Neovim CornelisEnv ()
forall a. a -> Neovim CornelisEnv a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    SplitLocation
OnTop      -> Window -> Int64 -> Neovim CornelisEnv ()
forall env. Window -> Int64 -> Neovim env ()
window_set_height Window
w Int64
size
    SplitLocation
OnBottom   -> Window -> Int64 -> Neovim CornelisEnv ()
forall env. Window -> Int64 -> Neovim env ()
window_set_height Window
w Int64
size



writeInfoBuffer :: Int64 -> InfoBuffer -> Doc HighlightGroup -> Neovim env ()
writeInfoBuffer :: forall env.
Int64 -> InfoBuffer -> Doc HighlightGroup -> Neovim env ()
writeInfoBuffer Int64
ns InfoBuffer
iw Doc HighlightGroup
doc = do
  -- TODO(sandy): Bad choice for a window, but good enough?
  Window
w <- Neovim env Window
forall env. Neovim env Window
nvim_get_current_win
  Int64
width <- Window -> Neovim env Int64
forall env. Window -> Neovim env Int64
window_get_width Window
w

  let sds :: SimpleDocStream HighlightGroup
sds = LayoutOptions
-> Doc HighlightGroup -> SimpleDocStream HighlightGroup
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty (PageWidth -> LayoutOptions
LayoutOptions (Int -> Double -> PageWidth
AvailablePerLine (Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
width) Double
0.8)) Doc HighlightGroup
doc
      ([InfoHighlight (Int64, Int64)]
hls, SimpleDocStream a
sds') = SimpleDocStream HighlightGroup
-> ([InfoHighlight (Int64, Int64)], SimpleDocStream a)
forall a.
SimpleDocStream HighlightGroup
-> ([InfoHighlight (Int64, Int64)], SimpleDocStream a)
renderWithHlGroups SimpleDocStream HighlightGroup
sds
      s :: [Text]
s = Text -> [Text]
T.lines (Text -> [Text]) -> Text -> [Text]
forall a b. (a -> b) -> a -> b
$ SimpleDocStream Any -> Text
forall ann. SimpleDocStream ann -> Text
renderStrict SimpleDocStream Any
forall {a}. SimpleDocStream a
sds'

  let b :: Buffer
b = InfoBuffer -> Buffer
iw_buffer InfoBuffer
iw
  Buffer -> Text -> Object -> Neovim env ()
forall env. Buffer -> Text -> Object -> Neovim env ()
nvim_buf_set_option Buffer
b Text
"modifiable" (Object -> Neovim env ()) -> Object -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ Bool -> Object
ObjectBool Bool
True
  Buffer -> Int64 -> Int64 -> Bool -> Vector Text -> Neovim env ()
forall env.
Buffer -> Int64 -> Int64 -> Bool -> Vector Text -> Neovim env ()
buffer_set_lines Buffer
b Int64
0 (-Int64
1) Bool
True (Vector Text -> Neovim env ()) -> Vector Text -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Vector Text
forall a. [a] -> Vector a
V.fromList [Text]
s

  [InfoHighlight Int64]
-> (InfoHighlight Int64 -> Neovim env Int64) -> Neovim env ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ ((InfoHighlight (Int64, Int64) -> [InfoHighlight Int64])
-> [InfoHighlight (Int64, Int64)] -> [InfoHighlight Int64]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap InfoHighlight (Int64, Int64) -> [InfoHighlight Int64]
spanInfoHighlights [InfoHighlight (Int64, Int64)]
hls) ((InfoHighlight Int64 -> Neovim env Int64) -> Neovim env ())
-> (InfoHighlight Int64 -> Neovim env Int64) -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ \(InfoHighlight (Int64
l, Int64
sc) Int64
ec HighlightGroup
hg) ->
    Buffer
-> Int64 -> Text -> Int64 -> Int64 -> Int64 -> Neovim env Int64
forall env.
Buffer
-> Int64 -> Text -> Int64 -> Int64 -> Int64 -> Neovim env Int64
nvim_buf_add_highlight
      Buffer
b Int64
ns
      (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ HighlightGroup -> String
forall a. Show a => a -> String
show HighlightGroup
hg)
      Int64
l Int64
sc Int64
ec
  Buffer -> Text -> Object -> Neovim env ()
forall env. Buffer -> Text -> Object -> Neovim env ()
nvim_buf_set_option Buffer
b Text
"modifiable" (Object -> Neovim env ()) -> Object -> Neovim env ()
forall a b. (a -> b) -> a -> b
$ Bool -> Object
ObjectBool Bool
False