Skip to content

Commit

Permalink
Update Caddyfile lexer to fix edgecases and improve colouring
Browse files Browse the repository at this point in the history
  • Loading branch information
francislavoie committed May 16, 2020
1 parent bd46305 commit d94559b
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 72 deletions.
112 changes: 55 additions & 57 deletions lexers/c/caddyfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import (
"github.com/alecthomas/chroma/lexers/internal"
)

// CaddyfileCommon are the rules common to both of the lexer variants
var CaddyfileCommon = Rules{
// caddyfileCommon are the rules common to both of the lexer variants
var caddyfileCommon = Rules{
"site_block_common": {
// Import keyword
{`(import)(\s+)([^\s]+)`, ByGroups(Keyword, Text, NameVariableMagic), nil},
// Matcher definition
{`@[^\s]+\s+`, NameDecorator, Push("matcher")},
{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")},
// Matcher token stub for docs
{`\[\<matcher\>\]`, NameDecorator, Push("matcher")},
// These cannot have matchers but may have things that look like
// matchers in their arguments, so we just parse as a subdirective.
{`try_files`, Keyword, Push("subdirective")},
// These are special, they can nest more directives
{`handle|route|handle_path|not`, Keyword, Push("nested_directive")},
{`handle_errors|handle|route|handle_path|not`, Keyword, Push("nested_directive")},
// Any other directive
{`[^\s#]+`, Keyword, Push("directive")},
Include("base"),
Expand All @@ -40,7 +45,9 @@ var CaddyfileCommon = Rules{
"nested_block": {
{`\}`, Punctuation, Pop(2)},
// Matcher definition
{`@[^\s]+\s+`, NameDecorator, Push("matcher")},
{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")},
// Something that starts with literally < is probably a docs stub
{`\<[^#]+\>`, Keyword, Push("nested_directive")},
// Any other directive
{`[^\s#]+`, Keyword, Push("nested_directive")},
Include("base"),
Expand All @@ -60,32 +67,33 @@ var CaddyfileCommon = Rules{
"directive": {
{`\{(?=\s)`, Punctuation, Push("block")},
Include("matcher_token"),
Include("comments_pop"),
Include("comments_pop_1"),
{`\n`, Text, Pop(1)},
Include("base"),
},
"nested_directive": {
{`\{(?=\s)`, Punctuation, Push("nested_block")},
Include("matcher_token"),
Include("comments_pop"),
Include("comments_pop_1"),
{`\n`, Text, Pop(1)},
Include("base"),
},
"subdirective": {
{`\{(?=\s)`, Punctuation, Push("block")},
Include("comments_pop"),
Include("comments_pop_1"),
{`\n`, Text, Pop(1)},
Include("base"),
},
"arguments": {
{`\{(?=\s)`, Punctuation, Push("block")},
Include("comments_pop"),
Include("comments_pop_2"),
{`\\\n`, Text, nil}, // Skip escaped newlines
{`\n`, Text, Pop(2)},
Include("base"),
},
"deep_subdirective": {
{`\{(?=\s)`, Punctuation, Push("block")},
Include("comments_pop"),
Include("comments_pop_3"),
{`\n`, Text, Pop(3)},
Include("base"),
},
Expand All @@ -99,30 +107,41 @@ var CaddyfileCommon = Rules{
{`^#.*\n`, CommentSingle, nil}, // Comment at start of line
{`\s+#.*\n`, CommentSingle, nil}, // Comment preceded by whitespace
},
"comments_pop": {
"comments_pop_1": {
{`^#.*\n`, CommentSingle, Pop(1)}, // Comment at start of line
{`\s+#.*\n`, CommentSingle, Pop(1)}, // Comment preceded by whitespace
},
"comments_pop_2": {
{`^#.*\n`, CommentSingle, Pop(2)}, // Comment at start of line
{`\s+#.*\n`, CommentSingle, Pop(2)}, // Comment preceded by whitespace
},
"comments_pop_3": {
{`^#.*\n`, CommentSingle, Pop(3)}, // Comment at start of line
{`\s+#.*\n`, CommentSingle, Pop(3)}, // Comment preceded by whitespace
},
"base": {
Include("comments"),
{`on|off`, NameConstant, nil},
{`on|off|first|last|before|after|internal|strip_prefix|strip_suffix|replace`, NameConstant, nil},
{`(https?://)?([a-z0-9.-]+)(:)([0-9]+)`, ByGroups(Name, Name, Punctuation, LiteralNumberInteger), nil},
{`[a-z-]+/[a-z-+]+`, LiteralString, nil},
{`[0-9]+[km]?\b`, LiteralNumberInteger, nil},
{`\{[\w+.-]+\}`, NameAttribute, nil}, // Placeholder
{`[^\s#{}$]+`, LiteralString, nil},
{`\{[\w+.-]+\}`, LiteralStringEscape, nil}, // Placeholder
{`\[(?=[^#{}$]+\])`, Punctuation, nil},
{`\]|\|`, Punctuation, nil},
{`[^\s#{}$\]]+`, LiteralString, nil},
{`/[^\s#]*`, Name, nil},
{`\s+`, Text, nil},
},
}

// CaddyfileRules are the merged rules for the main Caddyfile lexer
var CaddyfileRules = (func(a Rules, b Rules) Rules {
for k, v := range b {
a[k] = v
}
return a
})(
// Caddyfile lexer.
var Caddyfile = internal.Register(MustNewLexer(
&Config{
Name: "Caddyfile",
Aliases: []string{"caddyfile", "caddy"},
Filenames: []string{"Caddyfile*"},
MimeTypes: []string{},
},
Rules{
"root": {
Include("comments"),
Expand All @@ -131,28 +150,30 @@ var CaddyfileRules = (func(a Rules, b Rules) Rules {
// Snippets
{`(\([^\s#]+\))(\s*)(\{)`, ByGroups(NameVariableAnonymous, Text, Punctuation), Push("snippet")},
// Site label
{`[^#{(\s,]+`, NameLabel, Push("label")},
{`[^#{(\s,]+`, GenericHeading, Push("label")},
// Site label with placeholder
{`\{[\w+.-]+\}`, NameAttribute, Push("label")},
{`\s+`, Text, nil},
},
"globals": {
{`\}`, Punctuation, Pop(1)},
{`[^\s#]+`, KeywordType, Push("directive")},
{`[^\s#]+`, Keyword, Push("directive")},
Include("base"),
},
"snippet": {
{`\}`, Punctuation, Pop(1)},
// Matcher definition
{`@[^\s]+\s+`, NameDecorator, Push("matcher")},
{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")},
// Any directive
{`[^\s#]+`, KeywordType, Push("directive")},
{`[^\s#]+`, Keyword, Push("directive")},
Include("base"),
},
"label": {
{`,`, Text, nil},
// Allow multiple labels, comma separated, newlines after
// a comma means another label is coming
{`,\s*\n?`, Text, nil},
{` `, Text, nil},
{`[^#{(\s,]+`, NameLabel, nil},
{`[^#{(\s,]+`, GenericHeading, nil},
// Comment after non-block label (hack because comments end in \n)
{`#.*\n`, CommentSingle, Push("site_block")},
// Note: if \n, we'll never pop out of the site_block, it's valid
Expand All @@ -162,35 +183,7 @@ var CaddyfileRules = (func(a Rules, b Rules) Rules {
{`\}`, Punctuation, Pop(2)},
Include("site_block_common"),
},
},
CaddyfileCommon,
)

// CaddyfileDirectiveRules are the merged rules for the secondary lexer
var CaddyfileDirectiveRules = (func(a Rules, b Rules) Rules {
for k, v := range b {
a[k] = v
}
return a
})(
Rules{
// Same as "site_block" in Caddyfile
"root": {
Include("site_block_common"),
},
},
CaddyfileCommon,
)

// Caddyfile lexer.
var Caddyfile = internal.Register(MustNewLexer(
&Config{
Name: "Caddyfile",
Aliases: []string{"caddyfile", "caddy"},
Filenames: []string{"Caddyfile*"},
MimeTypes: []string{},
},
CaddyfileRules,
}.Merge(caddyfileCommon),
))

// Caddyfile directive-only lexer.
Expand All @@ -201,5 +194,10 @@ var CaddyfileDirectives = internal.Register(MustNewLexer(
Filenames: []string{},
MimeTypes: []string{},
},
CaddyfileDirectiveRules,
Rules{
// Same as "site_block" in Caddyfile
"root": {
Include("site_block_common"),
},
}.Merge(caddyfileCommon),
))
34 changes: 19 additions & 15 deletions lexers/testdata/caddyfile.expected
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n\t"},
{"type":"KeywordType","value":"debug"},
{"type":"Keyword","value":"debug"},
{"type":"Text","value":"\n\t"},
{"type":"KeywordType","value":"admin"},
{"type":"Keyword","value":"admin"},
{"type":"Text","value":" "},
{"type":"NameConstant","value":"off"},
{"type":"Text","value":"\n\t"},
{"type":"KeywordType","value":"on_demand_tls"},
{"type":"Keyword","value":"on_demand_tls"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n\t\t"},
Expand All @@ -23,7 +23,8 @@
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":" \n\t"},
{"type":"NameDecorator","value":"@blocked "},
{"type":"NameDecorator","value":"@blocked"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n\t\t"},
{"type":"Keyword","value":"path"},
Expand All @@ -38,17 +39,17 @@
{"type":"Text","value":"\n\t"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\t"},
{"type":"KeywordType","value":"redir"},
{"type":"Keyword","value":"redir"},
{"type":"Text","value":" "},
{"type":"NameDecorator","value":"@blocked"},
{"type":"Text","value":" "},
{"type":"LiteralString","value":"/"},
{"type":"Text","value":"\n"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n"},
{"type":"NameLabel","value":"example.com"},
{"type":"GenericHeading","value":"example.com"},
{"type":"Text","value":", "},
{"type":"NameLabel","value":"fake.org"},
{"type":"GenericHeading","value":"fake.org"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n\t"},
Expand All @@ -67,7 +68,8 @@
{"type":"Punctuation","value":"{"},
{"type":"CommentSingle","value":"\n\t\t# Add trailing slash for directory requests\n"},
{"type":"Text","value":"\t\t"},
{"type":"NameDecorator","value":"@canonicalPath "},
{"type":"NameDecorator","value":"@canonicalPath"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n\t\t\t"},
{"type":"Keyword","value":"file"},
Expand All @@ -76,7 +78,7 @@
{"type":"Text","value":"\n\t\t\t\t"},
{"type":"Keyword","value":"try_files"},
{"type":"Text","value":" "},
{"type":"NameAttribute","value":"{path}"},
{"type":"LiteralStringEscape","value":"{path}"},
{"type":"LiteralString","value":"/index.php"},
{"type":"Text","value":"\n\t\t\t"},
{"type":"Punctuation","value":"}"},
Expand All @@ -93,7 +95,7 @@
{"type":"Text","value":" "},
{"type":"NameDecorator","value":"@canonicalPath"},
{"type":"Text","value":" "},
{"type":"NameAttribute","value":"{path}"},
{"type":"LiteralStringEscape","value":"{path}"},
{"type":"LiteralString","value":"/"},
{"type":"Text","value":" "},
{"type":"LiteralNumberInteger","value":"308"},
Expand All @@ -109,9 +111,9 @@
{"type":"Text","value":"\n\t\t\t\t"},
{"type":"Keyword","value":"try_files"},
{"type":"Text","value":" "},
{"type":"NameAttribute","value":"{path}"},
{"type":"LiteralStringEscape","value":"{path}"},
{"type":"Text","value":" "},
{"type":"NameAttribute","value":"{path}"},
{"type":"LiteralStringEscape","value":"{path}"},
{"type":"LiteralString","value":"/index.php"},
{"type":"Text","value":" "},
{"type":"LiteralString","value":"index.php"},
Expand All @@ -128,7 +130,7 @@
{"type":"Text","value":" "},
{"type":"NameDecorator","value":"@indexFiles"},
{"type":"Text","value":" "},
{"type":"NameAttribute","value":"{http.matchers.file.relative}"},
{"type":"LiteralStringEscape","value":"{http.matchers.file.relative}"},
{"type":"CommentSingle","value":"\n\n\t\t# Proxy PHP files to the FastCGI responder\n"},
{"type":"Text","value":"\t\t"},
{"type":"NameDecorator","value":"@phpFiles"},
Expand Down Expand Up @@ -165,7 +167,8 @@
{"type":"Text","value":"\n\t"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n\t"},
{"type":"NameDecorator","value":"@encode_exts "},
{"type":"NameDecorator","value":"@encode_exts"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n\t\t"},
{"type":"Keyword","value":"path"},
Expand Down Expand Up @@ -216,7 +219,8 @@
{"type":"Text","value":"\n\t"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n\t"},
{"type":"NameDecorator","value":"@singleLine "},
{"type":"NameDecorator","value":"@singleLine"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"not"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"path"},
Expand Down

0 comments on commit d94559b

Please sign in to comment.