22
22
vimFile :: FilePath -> FilePath
24
24
case splitFileName file of
25
(path, name) -> path </> "" <.> name <.> "vim"
25
(path, name) -> path </> "" <.> name <.> "vim"
27
27
escape :: String -> String
28
28
escape = concatMap esc
30
escchars = "$\\^.*~[]"
31
esc c | c `elem` escchars = ['\\',c]
30
escchars = "$\\^.*~[]"
31
esc c | c `elem` escchars = ['\\',c]
34
34
wordBounded :: String -> String
35
35
wordBounded s0 = concat ["\\<", s0, "\\>"]
37
37
keyword :: String -> [String] -> String
39
keyword cat ws = "syn keyword " ++ unwords (cat : ws)
39
keyword cat ws = "syn keyword " ++ unwords (cat : ws)
41
41
match :: String -> [String] -> String
43
match cat ws = "syn match " ++ cat ++ " \"" ++
44
concat (List.intersperse "\\|" $ map (wordBounded . escape) ws) ++ "\""
43
match cat ws = "syn match " ++ cat ++ " \"" ++
44
concat (List.intersperse "\\|" $ map (wordBounded . escape) ws) ++ "\""
46
46
matches :: [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String]
47
47
matches cons icons defs idefs flds iflds =
49
49
$ List.sortBy (compare `on` fst)
50
50
$ cons' ++ defs' ++ icons' ++ idefs'
52
cons' = foo "agdaConstructor" $ classify length cons
53
icons' = foo "agdaInfixConstructor" $ classify length icons
54
defs' = foo "agdaFunction" $ classify length defs
55
idefs' = foo "agdaInfixFunction" $ classify length idefs
56
flds' = foo "agdaProjection" $ classify length flds
57
iflds' = foo "agdaInfixProjection" $ classify length iflds
59
classify f = List.groupBy ((==) `on` f)
60
. List.sortBy (compare `on` f)
62
foo :: String -> [[String]] -> [(Int, String)]
63
foo cat = map (length . head /\ match cat)
52
cons' = foo "agdaConstructor" $ classify length cons
53
icons' = foo "agdaInfixConstructor" $ classify length icons
54
defs' = foo "agdaFunction" $ classify length defs
55
idefs' = foo "agdaInfixFunction" $ classify length idefs
56
flds' = foo "agdaProjection" $ classify length flds
57
iflds' = foo "agdaInfixProjection" $ classify length iflds
59
classify f = List.groupBy ((==) `on` f)
60
. List.sortBy (compare `on` f)
62
foo :: String -> [[String]] -> [(Int, String)]
63
foo cat = map (length . head /\ match cat)
65
65
toVim :: NamesInScope -> String
66
66
toVim ns = unlines $ matches mcons micons mdefs midefs mflds miflds
68
cons = [ x | (x, def:_) <- Map.toList ns, anameKind def == ConName ]
69
defs = [ x | (x, def:_) <- Map.toList ns, anameKind def == DefName ]
70
flds = [ x | (x, fld:_) <- Map.toList ns, anameKind fld == FldName ]
76
micons = concatMap parts cons
77
midefs = concatMap parts defs
78
miflds = concatMap parts flds
80
parts (NoName _ _) = []
81
parts (Name _ [_]) = []
82
parts (Name _ ps) = [ rawNameToString x | Id x <- ps ]
68
cons = [ x | (x, def:_) <- Map.toList ns, anameKind def == ConName ]
69
defs = [ x | (x, def:_) <- Map.toList ns, anameKind def == DefName ]
70
flds = [ x | (x, fld:_) <- Map.toList ns, anameKind fld == FldName ]
76
micons = concatMap parts cons
77
midefs = concatMap parts defs
78
miflds = concatMap parts flds
80
parts (NoName _ _) = []
81
parts (Name _ [_]) = []
82
parts (Name _ ps) = [ rawNameToString x | Id x <- ps ]
84
84
generateVimFile :: FilePath -> TCM ()
85
85
generateVimFile file = do
87
87
liftIO $ UTF8.writeFile (vimFile file) $ toVim $ names scope
89
names = nsNames . everythingInScope
89
names = nsNames . everythingInScope