61 lines
2.3 KiB
Haskell
Raw Normal View History

2026-03-03 14:26:56 +00:00
module Datalog.LSP.Highlight where
2026-03-05 16:05:15 +00:00
import Control.Concurrent.STM
import Control.Monad.Trans
2026-03-03 14:26:56 +00:00
import Data.Either (fromRight)
2026-03-05 16:05:15 +00:00
import Data.Map qualified as M
import Data.Text qualified as T
import Datalog.LSP.Types (DLogLspM, LSPContext (..))
2026-03-05 16:05:15 +00:00
import Datalog.LSP.Utils (currentBufferUri)
2026-03-03 16:00:36 +00:00
import Datalog.Parser (SrcLoc (..))
import Datalog.Syntax (Atom' (Atom), Program' (..), RelId (RelId), Rule' (..), Term' (..))
2026-03-03 14:26:56 +00:00
import Language.LSP.Protocol.Message
import Language.LSP.Protocol.Types
import Language.LSP.Server
tokenHandler :: Handlers DLogLspM
2026-03-03 14:26:56 +00:00
tokenHandler = requestHandler SMethod_TextDocumentSemanticTokensFull $ \req responder -> do
LSPContext parseRef <- getConfig
p <- lift . readTVarIO $ parseRef
case M.lookup (currentBufferUri req) p of
2026-03-05 16:05:15 +00:00
Nothing ->
responder (Left $ TResponseError (InL LSPErrorCodes_RequestFailed) "Doc not bundle" Nothing)
Just (Left _) ->
responder (Left $ TResponseError (InL LSPErrorCodes_RequestFailed) "Failed to parse" Nothing)
Just (Right prog) -> do
2026-03-05 16:05:15 +00:00
responder
( Right
. InL
. fromRight (error "")
. makeSemanticTokens defaultSemanticTokensLegend
$ highlightProg prog
)
2026-03-03 16:00:36 +00:00
highlightProg :: Program' SrcLoc -> [SemanticTokenAbsolute]
highlightProg (Program _ rs) = rs >>= highlightRule
highlightRule :: Rule' SrcLoc -> [SemanticTokenAbsolute]
highlightRule (Rule _ a as) = a : as >>= highlightAtom
highlightAtom :: Atom' SrcLoc -> [SemanticTokenAbsolute]
highlightAtom (Atom loc (RelId relId) ts) = highlightRel ++ (ts >>= highlightTerm)
where
highlightRel = pure $ tokenFromSrcLoc loc' SemanticTokenTypes_Interface
loc' = loc{endCol = startCol loc + length (T.unpack relId)}
2026-03-03 16:00:36 +00:00
highlightTerm :: Term' SrcLoc -> [SemanticTokenAbsolute]
highlightTerm =
pure <$> \case
Con loc _ -> tokenFromSrcLoc loc SemanticTokenTypes_Number
Var loc _ -> tokenFromSrcLoc loc SemanticTokenTypes_Keyword
tokenFromSrcLoc :: SrcLoc -> SemanticTokenTypes -> SemanticTokenAbsolute
tokenFromSrcLoc (SrcLoc sl sc _ ec) tokenType =
SemanticTokenAbsolute
{ _line = fromIntegral $ sl - 1
, _startChar = fromIntegral $ sc - 1
, _length = fromIntegral $ ec - sc
, _tokenType = tokenType
2026-03-03 16:00:36 +00:00
, _tokenModifiers = []
}