3
3
module Swarm.DocGen (
4
4
generateDocs ,
5
5
GenerateDocs (.. ),
6
+ EditorType (.. ),
7
+
8
+ -- ** Formatted keyword lists
9
+ keywordsCommands ,
10
+ keywordsDirections ,
11
+ operatorNames ,
12
+ builtinCommandsListEmacs ,
13
+ editorList ,
6
14
) where
7
15
8
16
import Control.Lens (view , (^.) )
@@ -17,13 +25,17 @@ import Data.Maybe (fromMaybe)
17
25
import Data.Set (Set )
18
26
import Data.Set qualified as Set
19
27
import Data.Text (Text , unpack )
28
+ import Data.Text qualified as T
29
+ import Data.Text.IO qualified as T
20
30
import Data.Tuple (swap )
21
31
import Swarm.Game.Entity (Entity , EntityMap (entitiesByName ), entityName , loadEntities )
22
32
import Swarm.Game.Entity qualified as E
23
33
import Swarm.Game.Recipe (Recipe , loadRecipes , recipeInputs , recipeOutputs , recipeRequirements )
24
34
import Swarm.Game.Robot (installedDevices , robotInventory , setRobotID )
25
35
import Swarm.Game.Scenario (Scenario , loadScenario , scenarioRobots )
26
36
import Swarm.Game.WorldGen (testWorld2Entites )
37
+ import Swarm.Language.Syntax (Const (.. ), ConstMeta (.. ))
38
+ import Swarm.Language.Syntax qualified as Syntax
27
39
import Swarm.Util (isRightOr )
28
40
import Text.Dot (Dot , NodeId , (.->.) )
29
41
import Text.Dot qualified as Dot
@@ -39,11 +51,88 @@ import Text.Dot qualified as Dot
39
51
data GenerateDocs where
40
52
-- | Entity dependencies by recipes.
41
53
RecipeGraph :: GenerateDocs
54
+ -- | Keyword lists for editors.
55
+ EditorKeywords :: Maybe EditorType -> GenerateDocs
42
56
deriving (Eq , Show )
43
57
58
+ data EditorType = Emacs | VSCode
59
+ deriving (Eq , Show , Enum , Bounded )
60
+
44
61
generateDocs :: GenerateDocs -> IO ()
45
62
generateDocs = \ case
46
63
RecipeGraph -> generateRecipe >>= putStrLn
64
+ EditorKeywords e ->
65
+ case e of
66
+ Just et -> generateEditorKeywords et
67
+ Nothing -> do
68
+ putStrLn " All editor completions:"
69
+ let editorGen et = do
70
+ putStrLn $ replicate 40 ' -'
71
+ putStrLn $ " -- " <> show et
72
+ putStrLn $ replicate 40 ' -'
73
+ generateEditorKeywords et
74
+ mapM_ editorGen [minBound .. maxBound ]
75
+
76
+ -- ----------------------------------------------------------------------------
77
+ -- GENERATE KEYWORDS: LIST OF WORDS TO BE HIGHLIGHTED
78
+ -- ----------------------------------------------------------------------------
79
+
80
+ generateEditorKeywords :: EditorType -> IO ()
81
+ generateEditorKeywords = \ case
82
+ Emacs -> do
83
+ putStrLn " (x-builtins '("
84
+ T. putStr . editorList Emacs $ map constSyntax builtinCommandsEmacs
85
+ putStrLn " ))\n (x-commands '("
86
+ T. putStr $ keywordsCommands Emacs
87
+ T. putStr $ keywordsDirections Emacs
88
+ putStrLn " ))"
89
+ VSCode -> do
90
+ putStrLn " Functions and commands:"
91
+ T. putStrLn $ keywordsCommands VSCode
92
+ putStrLn " \n Directions:"
93
+ T. putStrLn $ keywordsDirections VSCode
94
+ putStrLn " \n Operators:"
95
+ T. putStrLn operatorNames
96
+
97
+ builtinCommandsEmacs :: [Const ]
98
+ builtinCommandsEmacs = [If , Run , Return , Try , Fail , Force , Fst , Snd ]
99
+
100
+ builtinCommandsListEmacs :: Text
101
+ builtinCommandsListEmacs = editorList Emacs $ map constSyntax builtinCommandsEmacs
102
+
103
+ editorList :: EditorType -> [Text ] -> Text
104
+ editorList = \ case
105
+ Emacs -> T. unlines . map ((" " <> ) . quote)
106
+ VSCode -> T. intercalate " |"
107
+ where
108
+ quote = T. cons ' "' . flip T. snoc ' "'
109
+
110
+ constSyntax :: Const -> Text
111
+ constSyntax = Syntax. syntax . Syntax. constInfo
112
+
113
+ -- | Get formatted list of basic functions/commands.
114
+ keywordsCommands :: EditorType -> Text
115
+ keywordsCommands e = editorList e $ map constSyntax (filter isFunc Syntax. allConst)
116
+ where
117
+ isFunc c = Syntax. isUserFunc c && (e /= Emacs || c `notElem` builtinCommandsEmacs)
118
+
119
+ -- | Get formatted list of directions.
120
+ keywordsDirections :: EditorType -> Text
121
+ keywordsDirections e = editorList e $ map (Syntax. dirSyntax . Syntax. dirInfo) Syntax. allDirs
122
+
123
+ operatorNames :: Text
124
+ operatorNames = T. intercalate " |" $ map (escape . constSyntax) (filter isOperator Syntax. allConst)
125
+ where
126
+ special :: String
127
+ special = " *+$[]|^"
128
+ slashNotComment = \ case
129
+ ' /' -> " /(?![/|*])"
130
+ c -> T. singleton c
131
+ escape = T. concatMap (\ c -> if c `elem` special then T. snoc " \\\\ " c else slashNotComment c)
132
+ isOperator c = case Syntax. constMeta $ Syntax. constInfo c of
133
+ ConstMUnOp {} -> True
134
+ ConstMBinOp {} -> True
135
+ ConstMFunc {} -> False
47
136
48
137
-- ----------------------------------------------------------------------------
49
138
-- GENERATE GRAPHVIZ: ENTITY DEPENDENCIES BY RECIPES
0 commit comments