Repository: alecthomas/chroma
Pull request #1057 (2025-03-03 18:46:42)

Add lexers.Aliases() method to display only lexers' aliases
`lexers.Aliases()` method shows all the aliases for all the available lexers, or their name if none are found. Using a flag, lexers without aliases can be skipped entirely.

This request addresses https://github.com/alecthomas/chroma/issues/1048.


Patch:
diff --git a/.golangci.yml b/.golangci.yml
index 7e98a22..91f313b 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,7 +1,5 @@
 run:
   tests: true
-  skip-dirs:
-    - _examples
 
 output:
   print-issued-lines: false
@@ -9,8 +7,6 @@ output:
 linters:
   enable-all: true
   disable:
-    - maligned
-    - megacheck
     - lll
     - gocyclo
     - dupl
@@ -18,9 +14,7 @@ linters:
     - funlen
     - godox
     - wsl
-    - gomnd
     - gocognit
-    - goerr113
     - nolintlint
     - testpackage
     - godot
@@ -28,12 +22,10 @@ linters:
     - paralleltest
     - nlreturn
     - cyclop
-    - exhaustivestruct
     - gci
     - gofumpt
     - errorlint
     - exhaustive
-    - ifshort
     - wrapcheck
     - stylecheck
     - thelper
@@ -46,7 +38,6 @@ linters:
     - ireturn
     - maintidx
     - govet
-    - nosnakecase
     - testableexamples
     - musttag
     - depguard
@@ -54,10 +45,11 @@ linters:
     - perfsprint
     - mnd
     - predeclared
+    - recvcheck
+    - tenv
+    - err113
 
 linters-settings:
-  govet:
-    check-shadowing: true
   gocyclo:
     min-complexity: 10
   dupl:
@@ -72,6 +64,8 @@ linters-settings:
 
 
 issues:
+  exclude-dirs:
+    - _examples
   max-per-linter: 0
   max-same: 0
   exclude-use-default: false
diff --git a/bin/.enumer-1.5.9.pkg b/bin/.enumer-1.5.11.pkg
similarity index 100%
rename from bin/.enumer-1.5.9.pkg
rename to bin/.enumer-1.5.11.pkg
diff --git a/bin/.esbuild-0.24.2.pkg b/bin/.esbuild-0.25.1.pkg
similarity index 100%
rename from bin/.esbuild-0.24.2.pkg
rename to bin/.esbuild-0.25.1.pkg
diff --git a/bin/.go-1.23.5.pkg b/bin/.go-1.24.1.pkg
similarity index 100%
rename from bin/.go-1.23.5.pkg
rename to bin/.go-1.24.1.pkg
diff --git a/bin/.golangci-lint-1.60.3.pkg b/bin/.golangci-lint-1.64.6.pkg
similarity index 100%
rename from bin/.golangci-lint-1.60.3.pkg
rename to bin/.golangci-lint-1.64.6.pkg
diff --git a/bin/.svu-2.2.0.pkg b/bin/.svu-3.2.2.pkg
similarity index 100%
rename from bin/.svu-2.2.0.pkg
rename to bin/.svu-3.2.2.pkg
diff --git a/bin/.watchexec-2.2.1.pkg b/bin/.watchexec-2.3.0.pkg
similarity index 100%
rename from bin/.watchexec-2.2.1.pkg
rename to bin/.watchexec-2.3.0.pkg
diff --git a/bin/enumer b/bin/enumer
index 83e7e9c..932dfb1 120000
--- a/bin/enumer
+++ b/bin/enumer
@@ -1,1 +1,1 @@
-.enumer-1.5.9.pkg
\ No newline at end of file
+.enumer-1.5.11.pkg
\ No newline at end of file
diff --git a/bin/esbuild b/bin/esbuild
index 7330df0..6bceb5d 120000
--- a/bin/esbuild
+++ b/bin/esbuild
@@ -1,1 +1,1 @@
-.esbuild-0.24.2.pkg
\ No newline at end of file
+.esbuild-0.25.1.pkg
\ No newline at end of file
diff --git a/bin/go b/bin/go
index abaace1..64209c2 120000
--- a/bin/go
+++ b/bin/go
@@ -1,1 +1,1 @@
-.go-1.23.5.pkg
\ No newline at end of file
+.go-1.24.1.pkg
\ No newline at end of file
diff --git a/bin/gofmt b/bin/gofmt
index abaace1..64209c2 120000
--- a/bin/gofmt
+++ b/bin/gofmt
@@ -1,1 +1,1 @@
-.go-1.23.5.pkg
\ No newline at end of file
+.go-1.24.1.pkg
\ No newline at end of file
diff --git a/bin/golangci-lint b/bin/golangci-lint
index 9fbbfeb..9a5e5f2 120000
--- a/bin/golangci-lint
+++ b/bin/golangci-lint
@@ -1,1 +1,1 @@
-.golangci-lint-1.60.3.pkg
\ No newline at end of file
+.golangci-lint-1.64.6.pkg
\ No newline at end of file
diff --git a/bin/svu b/bin/svu
index a8903da..3972a5a 120000
--- a/bin/svu
+++ b/bin/svu
@@ -1,1 +1,1 @@
-.svu-2.2.0.pkg
\ No newline at end of file
+.svu-3.2.2.pkg
\ No newline at end of file
diff --git a/bin/watchexec b/bin/watchexec
index 91ca910..1610f10 120000
--- a/bin/watchexec
+++ b/bin/watchexec
@@ -1,1 +1,1 @@
-.watchexec-2.2.1.pkg
\ No newline at end of file
+.watchexec-2.3.0.pkg
\ No newline at end of file
diff --git a/cmd/chroma/go.mod b/cmd/chroma/go.mod
index ce8acbc..6083cfe 100644
--- a/cmd/chroma/go.mod
+++ b/cmd/chroma/go.mod
@@ -2,18 +2,18 @@ module github.com/alecthomas/chroma/v2/cmd/chroma
 
 go 1.22
 
-toolchain go1.23.5
+toolchain go1.24.1
 
 replace github.com/alecthomas/chroma/v2 => ../../
 
 require (
 	github.com/alecthomas/chroma/v2 v2.15.0
-	github.com/alecthomas/kong v1.7.0
+	github.com/alecthomas/kong v1.9.0
 	github.com/mattn/go-colorable v0.1.14
 	github.com/mattn/go-isatty v0.0.20
 )
 
 require (
-	github.com/dlclark/regexp2 v1.11.4 // indirect
+	github.com/dlclark/regexp2 v1.11.5 // indirect
 	golang.org/x/sys v0.29.0 // indirect
 )
diff --git a/cmd/chroma/go.sum b/cmd/chroma/go.sum
index 8547969..3d9d1ea 100644
--- a/cmd/chroma/go.sum
+++ b/cmd/chroma/go.sum
@@ -15,6 +15,10 @@ github.com/alecthomas/kong v1.6.1 h1:/7bVimARU3uxPD0hbryPE8qWrS3Oz3kPQoxA/H2NKG8
 github.com/alecthomas/kong v1.6.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
 github.com/alecthomas/kong v1.7.0 h1:MnT8+5JxFDCvISeI6vgd/mFbAJwueJ/pqQNzZMsiqZE=
 github.com/alecthomas/kong v1.7.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
+github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE=
+github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
+github.com/alecthomas/kong v1.9.0 h1:Wgg0ll5Ys7xDnpgYBuBn/wPeLGAuK0NvYmEcisJgrIs=
+github.com/alecthomas/kong v1.9.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
 github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
 github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
 github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
@@ -22,6 +26,8 @@ github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxK
 github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
 github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
+github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
diff --git a/cmd/chromad/go.mod b/cmd/chromad/go.mod
index c1407a1..9fde152 100644
--- a/cmd/chromad/go.mod
+++ b/cmd/chromad/go.mod
@@ -2,11 +2,11 @@ module github.com/alecthomas/chroma/v2/cmd/chromad
 
 go 1.22
 
-toolchain go1.23.5
+toolchain go1.24.1
 
 require (
 	github.com/alecthomas/chroma/v2 v2.15.0
-	github.com/alecthomas/kong v1.7.0
+	github.com/alecthomas/kong v1.9.0
 	github.com/alecthomas/kong-hcl v1.0.1
 	github.com/gorilla/csrf v1.7.2
 	github.com/gorilla/handlers v1.5.2
@@ -14,7 +14,7 @@ require (
 )
 
 require (
-	github.com/dlclark/regexp2 v1.11.4 // indirect
+	github.com/dlclark/regexp2 v1.11.5 // indirect
 	github.com/felixge/httpsnoop v1.0.3 // indirect
 	github.com/gorilla/securecookie v1.1.2 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
diff --git a/cmd/chromad/go.sum b/cmd/chromad/go.sum
index cbcac40..3d50bf4 100644
--- a/cmd/chromad/go.sum
+++ b/cmd/chromad/go.sum
@@ -16,6 +16,10 @@ github.com/alecthomas/kong v1.6.1 h1:/7bVimARU3uxPD0hbryPE8qWrS3Oz3kPQoxA/H2NKG8
 github.com/alecthomas/kong v1.6.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
 github.com/alecthomas/kong v1.7.0 h1:MnT8+5JxFDCvISeI6vgd/mFbAJwueJ/pqQNzZMsiqZE=
 github.com/alecthomas/kong v1.7.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
+github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE=
+github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
+github.com/alecthomas/kong v1.9.0 h1:Wgg0ll5Ys7xDnpgYBuBn/wPeLGAuK0NvYmEcisJgrIs=
+github.com/alecthomas/kong v1.9.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
 github.com/alecthomas/kong-hcl v1.0.1 h1:f4svdFpEoNUwlpZj57CvfhzSnSfP/KBzMDETlwamd/s=
 github.com/alecthomas/kong-hcl v1.0.1/go.mod h1:6Y+MaMTZ/KQe9Qme6aSlKtql65FJE0/1O+Mu56C6UgQ=
 github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
@@ -27,6 +31,8 @@ github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxK
 github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
 github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
+github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
 github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
diff --git a/go.mod b/go.mod
index 551dfe3..9677945 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.22
 require (
 	github.com/alecthomas/assert/v2 v2.11.0
 	github.com/alecthomas/repr v0.4.0
-	github.com/dlclark/regexp2 v1.11.4
+	github.com/dlclark/regexp2 v1.11.5
 )
 
 require github.com/hexops/gotextdiff v1.0.3 // indirect
diff --git a/go.sum b/go.sum
index 9afa875..f9df122 100644
--- a/go.sum
+++ b/go.sum
@@ -4,5 +4,7 @@ github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc
 github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
 github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
 github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
+github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
 github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
diff --git a/lexers/embedded/lua.xml b/lexers/embedded/lua.xml
index 903d458..e3d778f 100644
--- a/lexers/embedded/lua.xml
+++ b/lexers/embedded/lua.xml
@@ -2,8 +2,10 @@
   <config>
     <name>Lua</name>
     <alias>lua</alias>
+    <alias>luau</alias>
     <filename>*.lua</filename>
     <filename>*.wlua</filename>
+    <filename>*.luau</filename>
     <mime_type>text/x-lua</mime_type>
     <mime_type>application/x-lua</mime_type>
   </config>
diff --git a/lexers/embedded/nginx_configuration_file.xml b/lexers/embedded/nginx_configuration_file.xml
index 46bdf57..a80d049 100644
--- a/lexers/embedded/nginx_configuration_file.xml
+++ b/lexers/embedded/nginx_configuration_file.xml
@@ -58,6 +58,9 @@
       <rule pattern="\$[^\s;#()]+">
         <token type="NameVariable"/>
       </rule>
+      <rule pattern="(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)">
+        <token type="Name"/>
+      </rule>
       <rule pattern="([a-z0-9.-]+)(:)([0-9]+)">
         <bygroups>
           <token type="Name"/>
diff --git a/lexers/lexers.go b/lexers/lexers.go
index 4fa35ad..bef42ed 100644
--- a/lexers/lexers.go
+++ b/lexers/lexers.go
@@ -29,6 +29,12 @@ func Names(withAliases bool) []string {
 	return GlobalLexerRegistry.Names(withAliases)
 }
 
+// Aliases of all the lexers, and skip those lexers who do not have any aliases,
+// or show their name instead
+func Aliases(skipWithoutAliases bool) []string {
+	return GlobalLexerRegistry.Aliases(skipWithoutAliases)
+}
+
 // Get a Lexer by name, alias or file extension.
 //
 // Note that this if there isn't an exact match on name or alias, this will
diff --git a/lexers/raku.go b/lexers/raku.go
index 8085bc7..49e03a4 100644
--- a/lexers/raku.go
+++ b/lexers/raku.go
@@ -1331,8 +1331,8 @@ func contains(s []string, e string) bool {
 type rulePosition int
 
 const (
-	topRule    rulePosition = 0
-	bottomRule              = -1
+	topRule rulePosition = 0 - iota
+	bottomRule
 )
 
 type ruleMakingConfig struct {
diff --git a/registry.go b/registry.go
index 4742e8c..a309af9 100644
--- a/registry.go
+++ b/registry.go
@@ -48,6 +48,24 @@ func (l *LexerRegistry) Names(withAliases bool) []string {
 	return out
 }
 
+// Aliases of all the lexers, and skip those lexers who do not have any aliases,
+// or show their name instead
+func (l *LexerRegistry) Aliases(skipWithoutAliases bool) []string {
+	out := []string{}
+	for _, lexer := range l.Lexers {
+		config := lexer.Config()
+		if len(config.Aliases) == 0 {
+			if skipWithoutAliases {
+				continue
+			}
+			out = append(out, config.Name)
+		}
+		out = append(out, config.Aliases...)
+	}
+	sort.Strings(out)
+	return out
+}
+
 // Get a Lexer by name, alias or file extension.
 func (l *LexerRegistry) Get(name string) Lexer {
 	if lexer := l.byName[name]; lexer != nil {


Test patch:
diff --git a/formatters/html/html_test.go b/formatters/html/html_test.go
index f7cff4f..7bd0cde 100644
--- a/formatters/html/html_test.go
+++ b/formatters/html/html_test.go
@@ -25,7 +25,7 @@ func TestCompressStyle(t *testing.T) {
 func BenchmarkHTMLFormatter(b *testing.B) {
 	formatter := New()
 	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
+	for range b.N {
 		it, err := lexers.Get("go").Tokenise(nil, "package main\nfunc main()\n{\nprintln(`hello world`)\n}\n")
 		assert.NoError(b, err)
 		err = formatter.Format(io.Discard, styles.Fallback, it)
diff --git a/lexers/lexer_benchmark_test.go b/lexers/lexer_benchmark_test.go
index 1fdf1fa..acb4117 100644
--- a/lexers/lexer_benchmark_test.go
+++ b/lexers/lexer_benchmark_test.go
@@ -209,7 +209,7 @@ public class CheckpointFile<T> {
 
 func Benchmark(b *testing.B) {
 	b.ReportAllocs()
-	for i := 0; i < b.N; i++ {
+	for range b.N {
 		it, err := lexers.GlobalLexerRegistry.Get("Java").Tokenise(nil, lexerBenchSource)
 		assert.NoError(b, err)
 		for t := it(); t != chroma.EOF; t = it() {
diff --git a/lexers/lexers_test.go b/lexers/lexers_test.go
index 57ea019..eb00c55 100644
--- a/lexers/lexers_test.go
+++ b/lexers/lexers_test.go
@@ -23,7 +23,7 @@ func TestCompileAllRegexes(t *testing.T) {
 	for _, lexer := range lexers.GlobalLexerRegistry.Lexers {
 		it, err := lexer.Tokenise(nil, "")
 		assert.NoError(t, err, "%s failed", lexer.Config().Name)
-		err = formatters.NoOp.Format(io.Discard, styles.SwapOff, it)
+		err = formatters.NoOp.Format(io.Discard, styles.Get("swapoff"), it)
 		assert.NoError(t, err, "%s failed", lexer.Config().Name)
 	}
 }
@@ -44,6 +44,19 @@ func TestGet(t *testing.T) {
 	})
 }
 
+func TestAliases(t *testing.T) {
+	t.Run("UseNameIfNoAliases", func(t *testing.T) {
+		expected := lexers.GlobalLexerRegistry.Aliases(false)
+		actual := lexers.Aliases(false)
+		assert.Equal(t, expected, actual)
+	})
+	t.Run("SkipIfNoAliases", func(t *testing.T) {
+		expected := lexers.GlobalLexerRegistry.Aliases(true)
+		actual := lexers.Aliases(true)
+		assert.Equal(t, expected, actual)
+	})
+}
+
 func TestGlobs(t *testing.T) {
 	filename := "main.go"
 	for _, lexer := range lexers.GlobalLexerRegistry.Lexers {
@@ -60,7 +73,7 @@ func TestGlobs(t *testing.T) {
 }
 
 func BenchmarkGet(b *testing.B) {
-	for i := 0; i < b.N; i++ {
+	for range b.N {
 		lexers.Get("go")
 	}
 }
diff --git a/lexers/testdata/nginx.actual b/lexers/testdata/nginx.actual
new file mode 100644
index 0000000..f57cb88
--- /dev/null
+++ b/lexers/testdata/nginx.actual
@@ -0,0 +1,31 @@
+http {
+    upstream app_backend {
+        server 127.0.0.1;
+        server 127.0.0.1:8082;
+        server backend.com;
+        server backend-2.com weight=5;
+        server backend-backup.org backup;
+    }
+
+    map $http_host $site_root {
+        default /var/www/default; # Default root
+        example.com /var/www/example_com;
+        example.org /var/www/example_org;
+    }
+
+    server {
+        listen 80 default_server;
+        server_name _;
+
+        root /var/www/default;
+
+        location / {
+            index index.html;
+        }
+
+        location /status {
+            return 200 "Default server status: OK\n";
+            add_header Content-Type text/plain;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lexers/testdata/nginx.expected b/lexers/testdata/nginx.expected
new file mode 100644
index 0000000..fba67c4
--- /dev/null
+++ b/lexers/testdata/nginx.expected
@@ -0,0 +1,137 @@
+[
+  {"type":"Keyword","value":"http"},
+  {"type":"Text","value":" "},
+  {"type":"Punctuation","value":"{"},
+  {"type":"Text","value":"\n    "},
+  {"type":"KeywordNamespace","value":"upstream"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"app_backend"},
+  {"type":"Text","value":" "},
+  {"type":"Punctuation","value":"{"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"server"},
+  {"type":"Text","value":" "},
+  {"type":"Name","value":"127.0.0.1"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"server"},
+  {"type":"Text","value":" "},
+  {"type":"Name","value":"127.0.0.1"},
+  {"type":"Punctuation","value":":"},
+  {"type":"LiteralNumberInteger","value":"8082"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"server"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"backend.com"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"server"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"backend-2.com"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"weight=5"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"server"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"backend-backup.org"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"backup"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n    "},
+  {"type":"Punctuation","value":"}"},
+  {"type":"Text","value":"\n\n    "},
+  {"type":"KeywordNamespace","value":"map"},
+  {"type":"Text","value":" "},
+  {"type":"NameVariable","value":"$http_host"},
+  {"type":"Text","value":" "},
+  {"type":"NameVariable","value":"$site_root"},
+  {"type":"Text","value":" "},
+  {"type":"Punctuation","value":"{"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"default"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"/var/www/default"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":" "},
+  {"type":"CommentSingle","value":"# Default root\n"},
+  {"type":"Text","value":"        "},
+  {"type":"KeywordNamespace","value":"example.com"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"/var/www/example_com"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"example.org"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"/var/www/example_org"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n    "},
+  {"type":"Punctuation","value":"}"},
+  {"type":"Text","value":"\n\n    "},
+  {"type":"KeywordNamespace","value":"server"},
+  {"type":"Text","value":" "},
+  {"type":"Punctuation","value":"{"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"listen"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralNumberInteger","value":"80"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"default_server"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"KeywordNamespace","value":"server_name"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"_"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n\n        "},
+  {"type":"KeywordNamespace","value":"root"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"/var/www/default"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n\n        "},
+  {"type":"KeywordNamespace","value":"location"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"/"},
+  {"type":"Text","value":" "},
+  {"type":"Punctuation","value":"{"},
+  {"type":"Text","value":"\n            "},
+  {"type":"KeywordNamespace","value":"index"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"index.html"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"Punctuation","value":"}"},
+  {"type":"Text","value":"\n\n        "},
+  {"type":"KeywordNamespace","value":"location"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"/status"},
+  {"type":"Text","value":" "},
+  {"type":"Punctuation","value":"{"},
+  {"type":"Text","value":"\n            "},
+  {"type":"KeywordNamespace","value":"return"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralNumberInteger","value":"200"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"\"Default"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"server"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"status:"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"OK\\n\""},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n            "},
+  {"type":"KeywordNamespace","value":"add_header"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"Content-Type"},
+  {"type":"Text","value":" "},
+  {"type":"LiteralString","value":"text/plain"},
+  {"type":"Punctuation","value":";"},
+  {"type":"Text","value":"\n        "},
+  {"type":"Punctuation","value":"}"},
+  {"type":"Text","value":"\n    "},
+  {"type":"Punctuation","value":"}"},
+  {"type":"Text","value":"\n"},
+  {"type":"Punctuation","value":"}"}
+]