cornelis-0.2.0.0: test/Utils.hs
{-# LANGUAGE NumDecimals #-}
{-# LANGUAGE OverloadedStrings #-}
module Utils
( module Utils
, Edit (..)
) where
import Control.Concurrent (threadDelay)
import Cornelis.Types
import Cornelis.Offsets
import Cornelis.Utils (withLocalEnv)
import Cornelis.Vim
import Data.Foldable.Levenshtein (levenshtein, Edit(..))
import qualified Data.Text as T
import qualified Data.Vector as V
import Lib
import Neovim
import Neovim.API.Text
import Neovim.Test
import Plugin
import System.FilePath (takeBaseName)
import System.IO (hFlush, hPutStr)
import System.IO.Temp (withSystemTempFile)
import Test.Hspec hiding (after, before)
-- data Diff a
-- = Insert a
-- | Delete a
-- | Modify a a
-- deriving (Eq, Ord, Show, Functor)
isCopy :: Edit a -> Bool
isCopy Copy{} = True
isCopy _ = False
diff :: Show a => Eq a => [a] -> [a] -> [Edit a]
diff = ((filter (not . isCopy) . snd) .) . levenshtein @_ @_ @_ @Int
-- (snd .) . go
-- where
-- go ([]) as = (length as, fmap Insert as)
-- go bs [] = (length bs, fmap Delete bs)
-- go (b : bs) (a : as)
-- | b == a = go bs as
-- | otherwise = do
-- let x = traceShowId $ bimap (+1) (Delete b :) $ go bs (a : as)
-- y = traceShowId $ bimap (+1) (Insert a :) $ go (b : bs) as
-- z = traceShowId $ bimap (+1) (Modify b a :) $ go bs as
-- minimumBy (comparing fst) [z, x, y]
differing :: Buffer -> Neovim env () -> Neovim env [Edit Text]
differing b m = do
before <- fmap V.toList $ buffer_get_lines b 0 (-1) False
m
liftIO $ threadDelay 1e6
after <- fmap V.toList $ buffer_get_lines b 0 (-1) False
pure $ diff before after
intervention :: Buffer -> [Edit Text] -> Neovim env () -> Neovim env ()
intervention b d m = do
d' <- differing b m
liftIO $ d' `shouldBe` d
withVim :: Seconds -> (Window -> Buffer -> Neovim () ()) -> IO ()
withVim secs m = do
let withNeovimEmbedded f = testWithEmbeddedNeovim f secs ()
withNeovimEmbedded Nothing $ do
b <- nvim_create_buf False False
w <- vim_get_current_window
nvim_win_set_buf w b
m w b
diffSpec
:: String
-> Seconds
-> FilePath
-> [Edit Text]
-> (Window -> Buffer -> Neovim CornelisEnv ())
-> Spec
diffSpec name secs fp diffs m =
vimSpec name secs fp $ \w b -> intervention b diffs $ m w b
vimSpec
:: String
-> Seconds
-> FilePath
-> (Window -> Buffer -> Neovim CornelisEnv ())
-> Spec
vimSpec name secs fp m = do
let withNeovimEmbedded f = testWithEmbeddedNeovim f secs ()
it name $ do
withSystemTempFile "test.agda" $ \fp' h -> do
hPutStr h $ "module " <> takeBaseName fp' <> " where\n"
hPutStr h . unlines . tail . lines =<< readFile fp
hFlush h
withNeovimEmbedded Nothing $ do
env <- cornelisInit
withLocalEnv env $ do
vim_command $ "edit " <> T.pack fp'
liftIO $ threadDelay 1e6
w <- vim_get_current_window
b <- nvim_win_get_buf w
load
liftIO $ threadDelay 5e6
m w b
goto :: Window -> Int -> Int -> Neovim env ()
goto w row col = setWindowCursor w $ Pos (toOneIndexed row) (toOneIndexed col)