module Neovim.Plugin.ConfigHelper.Internal
where
import Neovim.API.String (vim_command)
import Neovim.Config
import Neovim.Context
import Neovim.Plugin.Classes
import Neovim.Quickfix
import Neovim.Util (withCustomEnvironment)
import Neovim.Compat.Megaparsec as P hiding (count)
import Config.Dyre (Params)
import Config.Dyre.Compile
import Config.Dyre.Paths (getPaths)
import Control.Applicative hiding (many, (<|>))
import Control.Monad (void, forM_)
import Data.Char
import System.SetEnv
import System.Directory (removeDirectoryRecursive)
import Prelude
pingNvimhs :: Neovim' String
pingNvimhs = return "Pong"
recompileNvimhs :: Neovim (Params NeovimConfig, [(String, Maybe String)]) [QuickfixListItem String] ()
recompileNvimhs = ask >>= \(cfg,env) -> withCustomEnvironment env $ do
mErrString <- liftIO (customCompile cfg >> getErrorString cfg)
let qs = maybe [] parseQuickfixItems mErrString
put qs
setqflist qs Replace
void $ vim_command "cwindow"
restartNvimhs :: CommandArguments
-> Neovim (Params NeovimConfig, [(String, Maybe String)]) [QuickfixListItem String] ()
restartNvimhs CommandArguments{..} = do
case bang of
Just True -> do
(_,_,_, cacheDir,_) <- liftIO . getPaths =<< asks fst
liftIO $ removeDirectoryRecursive cacheDir
_ ->
return ()
recompileNvimhs
(_, env) <- ask
forM_ env $ \(var, val) -> liftIO $ do
maybe (unsetEnv var) (setEnv var) val
restart
parseQuickfixItems :: String -> [QuickfixListItem String]
parseQuickfixItems s =
case parse (P.many pQuickfixListItem) "Quickfix parser" s of
Right qs -> qs
Left _ -> []
pQuickfixListItem :: P.Parser (QuickfixListItem String)
pQuickfixListItem = do
_ <- P.many blankLine
(f,l,c) <- pLocation
void $ P.many tabOrSpace
e <- pSeverity
desc <- try pShortDesrciption <|> pLongDescription
return $ (quickfixListItem (Right f) (Left l))
{ col = Just (c, True)
, text = desc
, errorType = e
}
pSeverity :: P.Parser QuickfixErrorType
pSeverity = do
try (string "Warning:" *> return Warning)
<|> try (string "error:" *> return Error)
<|> return Error
pShortDesrciption :: P.Parser String
pShortDesrciption = (:)
<$> (notFollowedBy blankLine *> anyChar)
<*> anyChar `manyTill` (void (P.some blankLine) <|> eof)
pLongDescription :: P.Parser String
pLongDescription = anyChar `manyTill` (blank <|> eof)
where
blank = try (try newline *> try blankLine)
tabOrSpace :: P.Parser Char
tabOrSpace = satisfy $ \c -> c == ' ' || c == '\t'
blankLine :: P.Parser ()
blankLine = void .try $ P.many tabOrSpace >> newline
pLocation :: P.Parser (String, Int, Int)
pLocation = (,,)
<$> P.some (noneOf ":\n\t\r") <* char ':'
<*> pInt <* char ':'
<*> pInt <* char ':' <* P.many tabOrSpace
pInt :: P.Parser Int
pInt = read <$> P.some (satisfy isDigit)