Repository: sharkdp/bat (language: rust)

Issue:
Syntax highlighting for Racket
**Syntax:**
[Racket](https://racket-lang.org/)

**Guideline Criteria:**
[packagecontro.io/packages/Racket](https://packagecontrol.io/packages/Racket)



Discussion / hints:

Fix patch:
diff --git a/.gitmodules b/.gitmodules
index 5f28570cf8..2426d305a5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -230,3 +230,6 @@
 [submodule "assets/syntaxes/02_Extra/Slim"]
 	path = assets/syntaxes/02_Extra/Slim
 	url = https://github.com/slim-template/ruby-slim.tmbundle.git
+[submodule "assets/syntaxes/02_Extra/Racket"]
+	path = assets/syntaxes/02_Extra/Racket
+	url = https://github.com/follesoe/sublime-racket.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57563fce32..e8a775a987 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,7 @@
 - Highlight for `vimrc` and `gvimrc` files, see #1763 (@SuperSandro2000)
 - Syslog highlighting improvements, see #1793 (@scop)
 - Added support for `slim` syntax, see #1693 (@mfinelli)
+- Racket, see #1884 (@jubnzv)
 
 ## New themes
 
diff --git a/assets/syntaxes/02_Extra/Racket b/assets/syntaxes/02_Extra/Racket
new file mode 160000
index 0000000000..7df4479c07
--- /dev/null
+++ b/assets/syntaxes/02_Extra/Racket
@@ -0,0 +1,1 @@
+Subproject commit 7df4479c079768edd994b20052761152e277af21
diff --git a/assets/syntaxes/02_Extra/Racket.sublime-syntax b/assets/syntaxes/02_Extra/Racket.sublime-syntax
new file mode 100644
index 0000000000..82e2b852e9
--- /dev/null
+++ b/assets/syntaxes/02_Extra/Racket.sublime-syntax
@@ -0,0 +1,52 @@
+%YAML 1.2
+---
+# http://www.sublimetext.com/docs/3/syntax.html
+name: Racket
+file_extensions:
+  - rkt
+scope: source.racket
+contexts:
+  main:
+    - match: '[^\\](\"[^\"]*\")'
+      captures:
+        1: string.quoted.double.source.racket
+    - match: '\((define)\s+([a-zA-Z0-9_\-?\+^]+)\s*'
+      scope: meta.variable.source.racket
+      captures:
+        1: keyword.source.racket
+        2: entity.name.variable.source.racket
+    - match: '\((define)\s+\(([a-zA-Z0-9_\-?\+^]+)\s*'
+      scope: meta.function.source.racket
+      captures:
+        1: keyword.source.racket
+        2: entity.name.function
+    - match: '\((struct)\s+([a-zA-Z0-9_\-?\+^]+)\s+'
+      scope: meta.struct.source.racket
+      captures:
+        1: keyword.source.racket
+        2: entity.name.type
+    - match: '[\s\(](if|lambda|cond|define|type-case|let|letrec|let!|\#lang|require|test|else|first|rest|define-type|define-type-alias|define-struct|not|local|error|lang)[\s\)]'
+      scope: meta.keywords.source.racket
+      captures:
+        1: keyword.source.racket
+    - match: '[\s\(](true|false|empty|null)[\s\)]'
+      captures:
+        1: constant.language.source.racket
+    - match: '[\s\(\[\{](#t|#true|#f|#false)[\s\)\]\}]'
+      captures:
+        1: constant.language.source.racket
+    - match: '(#\\[a-zA-Z0-9_\-?\+\.\!\"]+)'
+      captures:
+        1: constant.language.source.racket
+    - match: '\b(0|([1-9][0-9_]*))\b'
+      scope: constant.numeric.integer.source.racket
+    - match: ;
+      push:
+        - meta_scope: comment.line.documentation.source.racket
+        - match: $\n
+          pop: true
+    - match: '#\|'
+      push:
+        - meta_scope: comment.block.source.racket
+        - match: '\|#'
+          pop: true


Test patch:
diff --git a/tests/syntax-tests/highlighted/Racket/test.rkt b/tests/syntax-tests/highlighted/Racket/test.rkt
new file mode 100644
index 0000000000..62281b08b1
--- /dev/null
+++ b/tests/syntax-tests/highlighted/Racket/test.rkt
@@ -0,0 +1,56 @@
+[38;2;248;248;242m#lang racket[0m
+
+[38;2;248;248;242m([0m[38;2;249;38;114mrequire[0m[38;2;248;248;242m [0m[38;2;248;248;242m"main.rkt" rackunit)[0m
+
+[38;2;117;113;94m;; Helper for test cases with multiple outputs[0m
+[38;2;117;113;94m;; See: https://stackoverflow.com/questions/41081395/unit-testing-in-racket-with-multiple-outputs[0m
+[38;2;248;248;242m(define-syntax check-values-equal?[0m
+[38;2;248;248;242m  (syntax-rules ()[0m
+[38;2;248;248;242m    [(_ a b) (check-equal? (call-with-values (thunk a) list) b)]))[0m
+
+
+[38;2;117;113;94m;; Named POSIX semaphores[0m
+[38;2;248;248;242m(test-begin[0m
+[38;2;248;248;242m  [0m[38;2;248;248;242m([0m[38;2;249;38;114mdefine[0m[38;2;248;248;242m [0m[38;2;166;226;46mtest-sem-name[0m[38;2;248;248;242m [0m[38;2;248;248;242m"/test-nix-[0m[38;2;190;132;255m1[0m[38;2;248;248;242m")[0m
+
+[38;2;248;248;242m  [0m[38;2;117;113;94m;; Unlink if already exists[0m
+[38;2;248;248;242m  (sem-unlink test-sem-name)[0m
+
+[38;2;248;248;242m  [0m[38;2;117;113;94m;; Open and unlink[0m
+[38;2;248;248;242m  [0m[38;2;248;248;242m([0m[38;2;249;38;114mdefine[0m[38;2;248;248;242m [0m[38;2;166;226;46mtest-sem-p[0m[38;2;248;248;242m [0m[38;2;248;248;242m(sem-open test-sem-name (+ O_CREAT O_EXCL)))[0m
+[38;2;248;248;242m  (check-not-false test-sem-p)[0m
+[38;2;248;248;242m  (check-not-equal? test-sem-p (void))[0m
+[38;2;248;248;242m  (check-exn exn:fail?[0m
+[38;2;248;248;242m             [0m[38;2;248;248;242m([0m[38;2;249;38;114mlambda[0m[38;2;248;248;242m [0m[38;2;248;248;242m() (sem-open test-sem-name (+ O_CREAT O_EXCL)))[0m
+[38;2;248;248;242m             [0m[38;2;230;219;116m"Permission denied"[0m[38;2;248;248;242m)[0m
+[38;2;248;248;242m  (check-exn exn:fail?[0m
+[38;2;248;248;242m             [0m[38;2;248;248;242m([0m[38;2;249;38;114mlambda[0m[38;2;248;248;242m [0m[38;2;248;248;242m() (sem-open test-sem-name (+ O_CREAT O_EXCL))))[0m
+
+[38;2;248;248;242m  [0m[38;2;117;113;94m;; Change values[0m
+[38;2;248;248;242m  (check-equal? (sem-getvalue test-sem-p) [0m[38;2;190;132;255m0[0m[38;2;248;248;242m)[0m
+[38;2;248;248;242m  (sem-post test-sem-p)[0m
+[38;2;248;248;242m  (check-equal? (sem-getvalue test-sem-p) [0m[38;2;190;132;255m1[0m[38;2;248;248;242m)[0m
+[38;2;248;248;242m  (sem-wait test-sem-p)[0m
+[38;2;248;248;242m  (check-equal? (sem-getvalue test-sem-p) [0m[38;2;190;132;255m0[0m[38;2;248;248;242m)[0m
+[38;2;248;248;242m  (sem-post test-sem-p)[0m
+[38;2;248;248;242m  (check-equal? (sem-getvalue test-sem-p) [0m[38;2;190;132;255m1[0m[38;2;248;248;242m)[0m
+[38;2;248;248;242m  (sem-post test-sem-p)[0m
+[38;2;248;248;242m  (check-equal? (sem-getvalue test-sem-p) [0m[38;2;190;132;255m2[0m[38;2;248;248;242m)[0m
+[38;2;248;248;242m  (sem-trywait test-sem-p)[0m
+[38;2;248;248;242m  (check-equal? (sem-getvalue test-sem-p) [0m[38;2;190;132;255m2[0m[38;2;248;248;242m)[0m
+
+[38;2;248;248;242m  [0m[38;2;117;113;94m;; Can't unlink twice[0m
+[38;2;248;248;242m  (check-not-false (sem-unlink test-sem-name))[0m
+[38;2;248;248;242m  (check-false (sem-unlink test-sem-name)))[0m
+
+
+[38;2;117;113;94m;; Named POSIX shared memory[0m
+[38;2;248;248;242m(test-begin[0m
+[38;2;248;248;242m  [0m[38;2;248;248;242m([0m[38;2;249;38;114mdefine[0m[38;2;248;248;242m [0m[38;2;166;226;46mtest-shm-name[0m[38;2;248;248;242m [0m[38;2;248;248;242m"test-nix-mem-[0m[38;2;190;132;255m1[0m[38;2;248;248;242m")[0m
+
+[38;2;248;248;242m  [0m[38;2;117;113;94m;; Open and unlink[0m
+[38;2;248;248;242m  (shm-unlink test-shm-name)[0m
+[38;2;248;248;242m  [0m[38;2;248;248;242m([0m[38;2;249;38;114mdefine[0m[38;2;248;248;242m [0m[38;2;166;226;46mtest-shm-fd[0m[38;2;248;248;242m [0m[38;2;248;248;242m(shm-open test-shm-name (+ O_EXCL O_CREAT O_RDWR) #o644))[0m
+[38;2;248;248;242m  (check > test-shm-fd [0m[38;2;190;132;255m0[0m[38;2;248;248;242m)[0m
+[38;2;248;248;242m  (check-not-false (shm-unlink test-shm-name))[0m
+[38;2;248;248;242m  (check-false (shm-unlink test-shm-name)))[0m
diff --git a/tests/syntax-tests/source/Racket/test.rkt b/tests/syntax-tests/source/Racket/test.rkt
new file mode 100644
index 0000000000..ed9a31316b
--- /dev/null
+++ b/tests/syntax-tests/source/Racket/test.rkt
@@ -0,0 +1,56 @@
+#lang racket
+
+(require "main.rkt" rackunit)
+
+;; Helper for test cases with multiple outputs
+;; See: https://stackoverflow.com/questions/41081395/unit-testing-in-racket-with-multiple-outputs
+(define-syntax check-values-equal?
+  (syntax-rules ()
+    [(_ a b) (check-equal? (call-with-values (thunk a) list) b)]))
+
+
+;; Named POSIX semaphores
+(test-begin
+  (define test-sem-name "/test-nix-1")
+
+  ;; Unlink if already exists
+  (sem-unlink test-sem-name)
+
+  ;; Open and unlink
+  (define test-sem-p (sem-open test-sem-name (+ O_CREAT O_EXCL)))
+  (check-not-false test-sem-p)
+  (check-not-equal? test-sem-p (void))
+  (check-exn exn:fail?
+             (lambda () (sem-open test-sem-name (+ O_CREAT O_EXCL)))
+             "Permission denied")
+  (check-exn exn:fail?
+             (lambda () (sem-open test-sem-name (+ O_CREAT O_EXCL))))
+
+  ;; Change values
+  (check-equal? (sem-getvalue test-sem-p) 0)
+  (sem-post test-sem-p)
+  (check-equal? (sem-getvalue test-sem-p) 1)
+  (sem-wait test-sem-p)
+  (check-equal? (sem-getvalue test-sem-p) 0)
+  (sem-post test-sem-p)
+  (check-equal? (sem-getvalue test-sem-p) 1)
+  (sem-post test-sem-p)
+  (check-equal? (sem-getvalue test-sem-p) 2)
+  (sem-trywait test-sem-p)
+  (check-equal? (sem-getvalue test-sem-p) 2)
+
+  ;; Can't unlink twice
+  (check-not-false (sem-unlink test-sem-name))
+  (check-false (sem-unlink test-sem-name)))
+
+
+;; Named POSIX shared memory
+(test-begin
+  (define test-shm-name "test-nix-mem-1")
+
+  ;; Open and unlink
+  (shm-unlink test-shm-name)
+  (define test-shm-fd (shm-open test-shm-name (+ O_EXCL O_CREAT O_RDWR) #o644))
+  (check > test-shm-fd 0)
+  (check-not-false (shm-unlink test-shm-name))
+  (check-false (shm-unlink test-shm-name)))