swarm-0.6.0.0: src/swarm-doc/Swarm/Doc/Keyword.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
-- |
-- SPDX-License-Identifier: BSD-3-Clause
-- Description: keywords for doc gen and testing
--
-- Collect keywords for documentation generation and testing.
module Swarm.Doc.Keyword (
EditorType (..),
-- ** Formatted keyword lists
keywordsCommands,
keywordsDirections,
operatorNames,
builtinFunctionList,
) where
import Data.List (nub)
import Data.Text (Text)
import Data.Text qualified as T
import Swarm.Doc.Util
import Swarm.Language.Syntax.Direction
import Swarm.Util (quote)
-- | An enumeration of the editors supported by Swarm (currently,
-- Emacs, VS Code and Vim).
data EditorType = Emacs | VSCode | Vim
deriving (Eq, Show, Enum, Bounded)
builtinFunctionList :: EditorType -> Text
builtinFunctionList e = editorList e $ map constSyntax builtinFunctions
editorList :: EditorType -> [Text] -> Text
editorList = \case
Emacs -> T.unlines . map ((" " <>) . quote)
VSCode -> T.intercalate "|"
Vim -> T.intercalate " "
-- | Get formatted list of basic functions/commands.
keywordsCommands :: EditorType -> Text
keywordsCommands e = editorList e $ map constSyntax commands
-- | Get formatted list of directions.
keywordsDirections :: EditorType -> Text
keywordsDirections e = editorList e $ map directionSyntax allDirs
-- | A list of the names of all the operators in the language.
-- These are reflective of how the different editors treat operators,
-- keywords, symbols etc differently.
-- In order to get the list of operators supported by Swarm language
-- irrespective of an editor, @map constSyntax operators@ should suffice.
operatorNames :: EditorType -> Text
operatorNames e = case e of
Emacs -> editorList e $ map constSyntax operators <> extraOperators
-- Vim needs a list of unique characters that can be matched over using a regex
Vim -> T.pack . nub . T.unpack . T.concat $ map constSyntax operators <> extraOperators
VSCode -> editorList e $ map (escape . constSyntax) operators <> extraOperators
where
slashNotComment = \case
'/' -> "/(?![/|*])"
c -> T.singleton c
special :: String
special = "*+$[]|^"
-- Extra operators appearing in different places. Eg: Type signatures.
extraOperators :: [Text]
extraOperators = [":"]
escape = T.concatMap (\c -> if c `elem` special then T.snoc "\\" c else slashNotComment c)