module Neovim.Quickfix
where
import Control.Applicative
import Control.Monad (void)
import Data.ByteString as BS (ByteString, all, elem)
import qualified Data.Map as Map
import Data.Maybe
import Data.MessagePack
import Data.Monoid
import Neovim.API.String
import Neovim.Classes
import Neovim.Context
import Neovim.RPC.FunctionCall
setqflist :: (Monoid strType, NvimObject strType)
=> [QuickfixListItem strType] -> QuickfixAction -> Neovim r st ()
setqflist qs a =
void . wait' $ vim_call_function "setqflist" [toObject qs, toObject a]
data QuickfixListItem strType = QFItem
{ bufOrFile :: Either Int strType
, lnumOrPattern :: Either Int strType
, col :: Maybe (Int, Bool)
, nr :: Maybe Int
, text :: strType
, errorType :: strType
} deriving (Eq, Show)
quickfixListItem :: (Monoid strType)
=> Either Int strType
-> Either Int strType
-> QuickfixListItem strType
quickfixListItem bufferOrFile lineOrPattern = QFItem
{ bufOrFile = bufferOrFile
, lnumOrPattern = lineOrPattern
, col = Nothing
, nr = Nothing
, text = mempty
, errorType = mempty
}
instance (Monoid strType, NvimObject strType)
=> NvimObject (QuickfixListItem strType) where
toObject QFItem{..} =
(toObject :: Map.Map ByteString Object -> Object) . Map.fromList $
[ either (\b -> ("bufnr", toObject b))
(\f -> ("filename", toObject f))
bufOrFile
, either (\l -> ("lnum", toObject l))
(\p -> ("pattern", toObject p))
lnumOrPattern
, ("type", toObject errorType)
, ("text", toObject text)
] ++ catMaybes
[ (\n -> ("nr", toObject n)) <$> nr
, (\(c,_) -> ("col", toObject c)) <$> col
, (\(_,t) -> ("vcol", toObject t)) <$> col
]
fromObject objectMap@(ObjectMap _) = do
m <- fromObject objectMap
let l :: NvimObject o => ByteString -> Either String o
l key = case Map.lookup key m of
Just o -> fromObject o
Nothing -> Left "Key not found."
bufOrFile <- case (l "bufnr", l "filename") of
(Right b, _) -> return $ Left b
(_, Right f) -> return $ Right f
_ -> throwError "No buffer number or file name inside quickfix list item."
lnumOrPattern <- case (l "lnum", l "pattern") of
(Right lnum, _) -> return $ Left lnum
(_, Right pat) -> return $ Right pat
_ -> throwError "No line number of search pattern inside quickfix list item."
let l' :: NvimObject o => ByteString -> Either String (Maybe o)
l' key = case Map.lookup key m of
Just o -> Just <$> fromObject o
Nothing -> return Nothing
nr <- l' "nr" >>= \case
Just 0 -> return Nothing
nr' -> return nr'
c <- l' "col"
v <- l' "vcol"
let col = do
c' <- c
v' <- v
case c' of
0 -> Nothing
_ -> Just (c',v')
text <- fromMaybe mempty <$> l' "text"
errorType <- fromMaybe mempty <$> l' "type"
return QFItem{..}
fromObject o = throwError $ "Could not deserialize QuickfixListItem, expected a map but received: " ++ show o
data QuickfixAction
= Append
| Replace
| New
deriving (Eq, Ord, Enum, Bounded, Show)
instance NvimObject QuickfixAction where
toObject = \case
Append -> ObjectBinary "a"
Replace -> ObjectBinary "r"
New -> ObjectBinary ""
fromObject o = case fromObject o of
Right "a" -> return Append
Right "r" -> return Replace
Right s | BS.all (`BS.elem` " \t\n\r") s -> return New
_ -> Left "Could not convert to QuickfixAction"