summaryrefslogtreecommitdiff
path: root/pygments
diff options
context:
space:
mode:
authorAnteru <bitbucket@ca.sh13.net>2018-11-24 16:39:17 +0000
committerAnteru <bitbucket@ca.sh13.net>2018-11-24 16:39:17 +0000
commit4c9f78c5b9f076ffd89d98d6315a26cd0d206e3a (patch)
treefdca9480859bdfb0de18266b8808e0a5a79c65cf /pygments
parent1649a38885dab4c193bf266ae63688396fbc8f14 (diff)
parentc1255470b48207d060454abcf2a0b3709db5904b (diff)
downloadpygments-4c9f78c5b9f076ffd89d98d6315a26cd0d206e3a.tar.gz
Merged in technomancy/pygments-main/fennel (pull request #783)
Add support for the Fennel programming language
Diffstat (limited to 'pygments')
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/lisp.py71
2 files changed, 71 insertions, 1 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index 574685f2..f9513e28 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -153,6 +153,7 @@ LEXERS = {
'FancyLexer': ('pygments.lexers.ruby', 'Fancy', ('fancy', 'fy'), ('*.fy', '*.fancypack'), ('text/x-fancysrc',)),
'FantomLexer': ('pygments.lexers.fantom', 'Fantom', ('fan',), ('*.fan',), ('application/x-fantom',)),
'FelixLexer': ('pygments.lexers.felix', 'Felix', ('felix', 'flx'), ('*.flx', '*.flxh'), ('text/x-felix',)),
+ 'FennelLexer': ('pygments.lexers.lisp', 'Fennel', (), ('*.fnl',), ()),
'FishShellLexer': ('pygments.lexers.shell', 'Fish', ('fish', 'fishshell'), ('*.fish', '*.load'), ('application/x-fish',)),
'FlatlineLexer': ('pygments.lexers.dsls', 'Flatline', ('flatline',), (), ('text/x-flatline',)),
'ForthLexer': ('pygments.lexers.forth', 'Forth', ('forth',), ('*.frt', '*.fs'), ('application/x-forth',)),
diff --git a/pygments/lexers/lisp.py b/pygments/lexers/lisp.py
index 258916df..f1494b13 100644
--- a/pygments/lexers/lisp.py
+++ b/pygments/lexers/lisp.py
@@ -19,7 +19,7 @@ from pygments.lexers.python import PythonLexer
__all__ = ['SchemeLexer', 'CommonLispLexer', 'HyLexer', 'RacketLexer',
'NewLispLexer', 'EmacsLispLexer', 'ShenLexer', 'CPSALexer',
- 'XtlangLexer']
+ 'XtlangLexer', 'FennelLexer']
class SchemeLexer(RegexLexer):
@@ -2619,3 +2619,72 @@ class XtlangLexer(RegexLexer):
include('scheme')
],
}
+
+class FennelLexer(RegexLexer):
+ """A lexer for the Fennel programming language <https://fennel-lang.org>
+
+ Fennel compiles to Lua, so all the Lua builtins are recognized as well
+ as the special forms that are particular to the Fennel compiler.
+ """
+ name = 'Fennel'
+ aliases = ['fennel', 'fnl']
+ filenames = ['*.fnl']
+
+ # these two lists are taken from fennel-mode.el:
+ # https://gitlab.com/technomancy/fennel-mode
+ # this list is current as of Fennel version 0.1.0.
+ special_forms = (
+ u'require-macros', u'eval-compiler',
+ u'do', u'values', u'if', u'when', u'each', u'for', u'fn', u'lambda',
+ u'λ', u'set', u'global', u'var', u'local', u'let', u'tset', u'doto',
+ u'set-forcibly!', u'defn', u'partial', u'while', u'or', u'and', u'true',
+ u'false', u'nil', u'.', u'+', u'..', u'^', u'-', u'*', u'%', u'/', u'>',
+ u'<', u'>=', u'<=', u'=', u'~=', u'#', u'...', u':', u'->', u'->>',
+ )
+
+ # Might be nicer to use the list from _lua_builtins.py but it's unclear how?
+ builtins = (
+ u'_G', u'_VERSION', u'arg', u'assert', u'bit32', u'collectgarbage',
+ u'coroutine', u'debug', u'dofile', u'error', u'getfenv',
+ u'getmetatable', u'io', u'ipairs', u'load', u'loadfile', u'loadstring',
+ u'math', u'next', u'os', u'package', u'pairs', u'pcall', u'print',
+ u'rawequal', u'rawget', u'rawlen', u'rawset', u'require', u'select',
+ u'setfenv', u'setmetatable', u'string', u'table', u'tonumber',
+ u'tostring', u'type', u'unpack', u'xpcall'
+ )
+
+ # based on the scheme definition, but disallowing leading digits and commas
+ valid_name = r'[a-zA-Z_!$%&*+/:<=>?@^~|-][\w!$%&*+/:<=>?@^~|\.-]*'
+
+ tokens = {
+ 'root': [
+ # the only comment form is a semicolon; goes to the end of the line
+ (r';.*$', Comment.Single),
+
+ (r'[,\s]+', Text),
+ (r'-?\d+\.\d+', Number.Float),
+ (r'-?\d+', Number.Integer),
+
+ (r'"(\\\\|\\"|[^"])*"', String),
+ (r"'(\\\\|\\'|[^'])*'", String),
+
+ # these are technically strings, but it's worth visually
+ # distinguishing them because their intent is different
+ # from regular strings.
+ (r':' + valid_name, String.Symbol),
+
+ # special forms are keywords
+ (words(special_forms, suffix=' '), Keyword),
+ # lua standard library are builtins
+ (words(builtins, suffix=' '), Name.Builtin),
+ # special-case the vararg symbol
+ (r'\.\.\.', Name.Variable),
+ # regular identifiers
+ (valid_name, Name.Variable),
+
+ # all your normal paired delimiters for your programming enjoyment
+ (r'(\(|\))', Punctuation),
+ (r'(\[|\])', Punctuation),
+ (r'(\{|\})', Punctuation),
+ ]
+ }