module Agda.Interaction.Highlighting.Emacs
( clearSyntaxInfo
, writeEmacsFile
, appendErrorToEmacsFile
, Agda.Interaction.Highlighting.Emacs.tests
) where
import Agda.Interaction.Highlighting.Precise
import Agda.Interaction.Highlighting.Range
import Agda.Interaction.Highlighting.Generate
import Agda.TypeChecking.Monad (TCM, TCErr)
import Agda.Syntax.Abstract (QName)
import Agda.Syntax.Common
import qualified Agda.Syntax.Position as P
import Agda.Syntax.Translation.ConcreteToAbstract (TopLevelInfo)
import Agda.TypeChecking.Errors (prettyError)
import Agda.Utils.FileName
import Agda.Utils.String
import Agda.Utils.TestHelpers
import Control.Monad.Trans
import Data.List
import Data.Char
import Data.Maybe
import qualified System.IO.UTF8 as UTF8
toAtoms :: MetaInfo -> [String]
toAtoms m = map toAtom (otherAspects m) ++ toAtoms' (aspect m)
where
toAtom x = map toLower (show x)
kindToAtom (Constructor Inductive) = "inductiveconstructor"
kindToAtom (Constructor CoInductive) = "coinductiveconstructor"
kindToAtom k = toAtom k
toAtoms' Nothing = []
toAtoms' (Just (Name mKind op)) =
map kindToAtom (maybeToList mKind) ++ opAtom
where opAtom | op = ["operator"]
| otherwise = []
toAtoms' (Just a) = [toAtom a]
showMetaInfo :: (Range, MetaInfo) -> String
showMetaInfo (r, m) =
"(annotation-annotate "
++ show (from r)
++ " "
++ show (to r)
++ " '("
++ concat (intersperse " " (toAtoms m))
++ ")"
++ (maybe " nil" ((" " ++) . quote) $ note m)
++ (maybe ""
(\(_, f, p) -> " '(" ++ quote f ++ " . " ++ show p ++ ")")
$ definitionSite m)
++ ")"
showFile :: CompressedFile -> String
showFile = unlines . map showMetaInfo
infoFileName :: FilePath -> String
infoFileName path | null dir = base
| otherwise = dir ++ slash : base
where
(dir, name, ext) = splitFilePath path
base = '.' : name ++ ext ++ ".el"
clearSyntaxInfo
:: FilePath
-> IO ()
clearSyntaxInfo path = UTF8.writeFile (infoFileName path) ""
appendSyntaxInfo :: HighlightingInfo -> IO ()
appendSyntaxInfo highlighting =
UTF8.appendFile (infoFileName $ source highlighting)
(showFile $ info highlighting)
writeEmacsFile :: HighlightingInfo -> TCM ()
writeEmacsFile highlighting = do
liftIO $ clearSyntaxInfo (source highlighting)
liftIO $ appendSyntaxInfo highlighting
appendErrorToEmacsFile :: TCErr -> TCM ()
appendErrorToEmacsFile err = do
let r = P.getRange err
s <- prettyError err
case P.rStart r of
Nothing -> return ()
Just (P.Pn { P.srcFile = "" }) -> return ()
Just pos@(P.Pn { P.srcFile = f, P.posPos = p }) -> do
liftIO $ appendSyntaxInfo $
HighlightingInfo { source = f
, info = compress $ generateErrorInfo r s
}
tests :: IO Bool
tests = runTests "Agda.Interaction.Highlighting.Emacs" []