Commit 225dd3f7316ad8a18454aee499795433656c1615

Michael Schmidt 2018-11-29T14:07:27

Scheme improvements (#1556) 1. `)` is part for symbols (strings). 2. Function names which have a keyword/builtin as a prefix are not matched correctly. 3. Zero-length function names. 4. `'` is highlighted as `string` even if it marks a list. Also add support for Scheme characters.

diff --git a/components/prism-scheme.js b/components/prism-scheme.js
index 102d848..f402447 100644
--- a/components/prism-scheme.js
+++ b/components/prism-scheme.js
@@ -1,29 +1,33 @@
 Prism.languages.scheme = {
-	'comment' : /;.*/,
-	'string' :  {
-		pattern: /"(?:[^"\\\r\n]|\\.)*"|'[^('\s]*/,
+	'comment': /;.*/,
+	'string': {
+		pattern: /"(?:[^"\\\r\n]|\\.)*"|'[^()#'\s]+/,
 		greedy: true
 	},
-	'keyword' : {
-		pattern : /(\()(?:define(?:-syntax|-library|-values)?|(?:case-)?lambda|let(?:\*|rec)?(?:-values)?|else|if|cond|begin|delay(?:-force)?|parameterize|guard|set!|(?:quasi-)?quote|syntax-rules)/,
-		lookbehind : true
+	'character': {
+		pattern: /#\\(?:u[a-fA-F\d]{4}|[a-zA-Z]+|\S)/,
+		alias: 'string'
 	},
-	'builtin' : {
-		pattern :  /(\()(?:(?:cons|car|cdr|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?)/,
-		lookbehind : true
+	'keyword': {
+		pattern: /(\()(?:define(?:-syntax|-library|-values)?|(?:case-)?lambda|let(?:\*|rec)?(?:-values)?|else|if|cond|begin|delay(?:-force)?|parameterize|guard|set!|(?:quasi-)?quote|syntax-rules)(?=[()\s])/,
+		lookbehind: true
+	},
+	'builtin': {
+		pattern: /(\()(?:(?:cons|car|cdr|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?)(?=[()\s])/,
+		lookbehind: true
 	},
-	'number' : {
+	'number': {
 		pattern: /(\s|[()])[-+]?\d*\.?\d+(?:\s*[-+]\s*\d*\.?\d+i)?\b/,
 		lookbehind: true
 	},
-	'boolean' : /#[tf]/,
+	'boolean': /#[tf]/,
 	'operator': {
 		pattern: /(\()(?:[-+*%\/]|[<>]=?|=>?)/,
 		lookbehind: true
 	},
-	'function' : {
-		pattern : /(\()[^\s()]*(?=[\s)])/,
-		lookbehind : true
+	'function': {
+		pattern: /(\()[^()#'\s]+(?=[()\s)])/,
+		lookbehind: true
 	},
-	'punctuation' : /[()]/
-};
\ No newline at end of file
+	'punctuation': /[()']/
+};
diff --git a/components/prism-scheme.min.js b/components/prism-scheme.min.js
index 1767130..9b41709 100644
--- a/components/prism-scheme.min.js
+++ b/components/prism-scheme.min.js
@@ -1 +1 @@
-Prism.languages.scheme={comment:/;.*/,string:{pattern:/"(?:[^"\\\r\n]|\\.)*"|'[^('\s]*/,greedy:!0},keyword:{pattern:/(\()(?:define(?:-syntax|-library|-values)?|(?:case-)?lambda|let(?:\*|rec)?(?:-values)?|else|if|cond|begin|delay(?:-force)?|parameterize|guard|set!|(?:quasi-)?quote|syntax-rules)/,lookbehind:!0},builtin:{pattern:/(\()(?:(?:cons|car|cdr|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?)/,lookbehind:!0},number:{pattern:/(\s|[()])[-+]?\d*\.?\d+(?:\s*[-+]\s*\d*\.?\d+i)?\b/,lookbehind:!0},"boolean":/#[tf]/,operator:{pattern:/(\()(?:[-+*%\/]|[<>]=?|=>?)/,lookbehind:!0},"function":{pattern:/(\()[^\s()]*(?=[\s)])/,lookbehind:!0},punctuation:/[()]/};
\ No newline at end of file
+Prism.languages.scheme={comment:/;.*/,string:{pattern:/"(?:[^"\\\r\n]|\\.)*"|'[^()#'\s]+/,greedy:!0},character:{pattern:/#\\(?:u[a-fA-F\d]{4}|[a-zA-Z]+|\S)/,alias:"string"},keyword:{pattern:/(\()(?:define(?:-syntax|-library|-values)?|(?:case-)?lambda|let(?:\*|rec)?(?:-values)?|else|if|cond|begin|delay(?:-force)?|parameterize|guard|set!|(?:quasi-)?quote|syntax-rules)(?=[()\s])/,lookbehind:!0},builtin:{pattern:/(\()(?:(?:cons|car|cdr|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?)(?=[()\s])/,lookbehind:!0},number:{pattern:/(\s|[()])[-+]?\d*\.?\d+(?:\s*[-+]\s*\d*\.?\d+i)?\b/,lookbehind:!0},"boolean":/#[tf]/,operator:{pattern:/(\()(?:[-+*%\/]|[<>]=?|=>?)/,lookbehind:!0},"function":{pattern:/(\()[^()#'\s]+(?=[()\s)])/,lookbehind:!0},punctuation:/[()']/};
\ No newline at end of file
diff --git a/tests/languages/scheme/builtin_feature.test b/tests/languages/scheme/builtin_feature.test
index 4f9cf90..ab03c8e 100644
--- a/tests/languages/scheme/builtin_feature.test
+++ b/tests/languages/scheme/builtin_feature.test
@@ -1,53 +1,53 @@
-(cons
-(car
-(cdr
-(null?
-(pair?
-(boolean?
-(eof-object?
-(char?
-(procedure?
-(number?
-(port?
-(string?
-(vector?
-(symbol?
-(bytevector?
-(list
-(call-with-current-continuation
-(call/cc
-(append
-(abs
-(apply
-(eval
+(cons)
+(car)
+(cdr)
+(null?)
+(pair?)
+(boolean?)
+(eof-object?)
+(char?)
+(procedure?)
+(number?)
+(port?)
+(string?)
+(vector?)
+(symbol?)
+(bytevector?)
+(list)
+(call-with-current-continuation)
+(call/cc)
+(append)
+(abs)
+(apply)
+(eval)
 
 ----------------------------------------------------
 
 [
-	["punctuation", "("], ["builtin", "cons"],
-	["punctuation", "("], ["builtin", "car"],
-	["punctuation", "("], ["builtin", "cdr"],
-	["punctuation", "("], ["builtin", "null?"],
-	["punctuation", "("], ["builtin", "pair?"],
-	["punctuation", "("], ["builtin", "boolean?"],
-	["punctuation", "("], ["builtin", "eof-object?"],
-	["punctuation", "("], ["builtin", "char?"],
-	["punctuation", "("], ["builtin", "procedure?"],
-	["punctuation", "("], ["builtin", "number?"],
-	["punctuation", "("], ["builtin", "port?"],
-	["punctuation", "("], ["builtin", "string?"],
-	["punctuation", "("], ["builtin", "vector?"],
-	["punctuation", "("], ["builtin", "symbol?"],
-	["punctuation", "("], ["builtin", "bytevector?"],
-	["punctuation", "("], ["builtin", "list"],
-	["punctuation", "("], ["builtin", "call-with-current-continuation"],
-	["punctuation", "("], ["builtin", "call/cc"],
-	["punctuation", "("], ["builtin", "append"],
-	["punctuation", "("], ["builtin", "abs"],
-	["punctuation", "("], ["builtin", "apply"],
-	["punctuation", "("], ["builtin", "eval"]
+	["punctuation", "("], ["builtin", "cons"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "car"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "cdr"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "null?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "pair?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "boolean?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "eof-object?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "char?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "procedure?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "number?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "port?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "string?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "vector?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "symbol?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "bytevector?"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "list"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "call-with-current-continuation"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "call/cc"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "append"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "abs"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "apply"], ["punctuation", ")"],
+	["punctuation", "("], ["builtin", "eval"], ["punctuation", ")"]
 ]
 
 ----------------------------------------------------
 
-Checks for builtins.
\ No newline at end of file
+Checks for builtins.
diff --git a/tests/languages/scheme/character_feature.test b/tests/languages/scheme/character_feature.test
new file mode 100644
index 0000000..14e40cd
--- /dev/null
+++ b/tests/languages/scheme/character_feature.test
@@ -0,0 +1,19 @@
+#\a
+#\space
+#\u0041
+#\λ
+#\)
+
+----------------------------------------------------
+
+[
+	["character", "#\\a"],
+	["character", "#\\space"],
+	["character", "#\\u0041"],
+	["character", "#\\λ"],
+	["character", "#\\)"]
+]
+
+----------------------------------------------------
+
+Checks for character literals.
diff --git a/tests/languages/scheme/function_feature.test b/tests/languages/scheme/function_feature.test
index 4d8807c..f7c6547 100644
--- a/tests/languages/scheme/function_feature.test
+++ b/tests/languages/scheme/function_feature.test
@@ -3,6 +3,7 @@
 (exact? 2)
 (inexact->exact 3)
 (!fact)
+(defined foo)
 
 ----------------------------------------------------
 
@@ -11,7 +12,8 @@
 	["punctuation", "("], ["function", "flmin"], ["number", "2"], ["number", "3"], ["punctuation", ")"],
 	["punctuation", "("], ["function", "exact?"], ["number", "2"], ["punctuation", ")"],
 	["punctuation", "("], ["function", "inexact->exact"], ["number", "3"], ["punctuation", ")"],
-	["punctuation", "("], ["function", "!fact"], ["punctuation", ")"]
+	["punctuation", "("], ["function", "!fact"], ["punctuation", ")"],
+	["punctuation", "("], ["function", "defined"], " foo", ["punctuation", ")"]
 ]
 
 ----------------------------------------------------
diff --git a/tests/languages/scheme/issue1331.test b/tests/languages/scheme/issue1331.test
index ddbfff5..b8026d9 100644
--- a/tests/languages/scheme/issue1331.test
+++ b/tests/languages/scheme/issue1331.test
@@ -4,9 +4,9 @@
 
 [
 	["punctuation", "("], ["builtin", "pair?"],
-	["string", "'"], ["punctuation", "("], ["number", "1"], ["number", "2"], ["punctuation", ")"], ["punctuation", ")"]
+	["punctuation", "'"], ["punctuation", "("], ["number", "1"], ["number", "2"], ["punctuation", ")"], ["punctuation", ")"]
 ]
 
 ----------------------------------------------------
 
-Tests that first number of a list is not highlighted as a function. See #1331
\ No newline at end of file
+Tests that first number of a list is not highlighted as a function. See #1331
diff --git a/tests/languages/scheme/keyword_feature.test b/tests/languages/scheme/keyword_feature.test
index 534d8a0..1abc828 100644
--- a/tests/languages/scheme/keyword_feature.test
+++ b/tests/languages/scheme/keyword_feature.test
@@ -1,57 +1,57 @@
-(define
-(define-syntax
-(define-library
-(define-values
-(case-lambda
-(lambda
-(let
-(let*
-(letrec
-(let-values
-(let*-values
-(letrec-values
-(else
-(if
-(cond
-(begin
-(delay
-(delay-force
-(parameterize
-(guard
-(set!
-(quasi-quote
-(quote
-(syntax-rules
+(define)
+(define-syntax)
+(define-library)
+(define-values)
+(case-lambda)
+(lambda)
+(let)
+(let*)
+(letrec)
+(let-values)
+(let*-values)
+(letrec-values)
+(else)
+(if)
+(cond)
+(begin)
+(delay)
+(delay-force)
+(parameterize)
+(guard)
+(set!)
+(quasi-quote)
+(quote)
+(syntax-rules)
 
 ----------------------------------------------------
 
 [
-	["punctuation", "("], ["keyword", "define"],
-	["punctuation", "("], ["keyword", "define-syntax"],
-	["punctuation", "("], ["keyword", "define-library"],
-	["punctuation", "("], ["keyword", "define-values"],
-	["punctuation", "("], ["keyword", "case-lambda"],
-	["punctuation", "("], ["keyword", "lambda"],
-	["punctuation", "("], ["keyword", "let"],
-	["punctuation", "("], ["keyword", "let*"],
-	["punctuation", "("], ["keyword", "letrec"],
-	["punctuation", "("], ["keyword", "let-values"],
-	["punctuation", "("], ["keyword", "let*-values"],
-	["punctuation", "("], ["keyword", "letrec-values"],
-	["punctuation", "("], ["keyword", "else"],
-	["punctuation", "("], ["keyword", "if"],
-	["punctuation", "("], ["keyword", "cond"],
-	["punctuation", "("], ["keyword", "begin"],
-	["punctuation", "("], ["keyword", "delay"],
-	["punctuation", "("], ["keyword", "delay-force"],
-	["punctuation", "("], ["keyword", "parameterize"],
-	["punctuation", "("], ["keyword", "guard"],
-	["punctuation", "("], ["keyword", "set!"],
-	["punctuation", "("], ["keyword", "quasi-quote"],
-	["punctuation", "("], ["keyword", "quote"],
-	["punctuation", "("], ["keyword", "syntax-rules"]
+	["punctuation", "("], ["keyword", "define"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "define-syntax"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "define-library"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "define-values"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "case-lambda"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "lambda"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "let"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "let*"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "letrec"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "let-values"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "let*-values"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "letrec-values"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "else"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "if"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "cond"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "begin"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "delay"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "delay-force"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "parameterize"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "guard"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "set!"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "quasi-quote"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "quote"], ["punctuation", ")"],
+	["punctuation", "("], ["keyword", "syntax-rules"], ["punctuation", ")"]
 ]
 
 ----------------------------------------------------
 
-Checks for keywords.
\ No newline at end of file
+Checks for keywords.
diff --git a/tests/languages/scheme/string_feature.test b/tests/languages/scheme/string_feature.test
index a1f2a97..7369424 100644
--- a/tests/languages/scheme/string_feature.test
+++ b/tests/languages/scheme/string_feature.test
@@ -1,15 +1,17 @@
 ""
 "fo\"obar"
 'turkey
+(define a 'foo)
 
 ----------------------------------------------------
 
 [
 	["string", "\"\""],
 	["string", "\"fo\\\"obar\""],
-	["string", "'turkey"]
+	["string", "'turkey"],
+	["punctuation", "("], ["keyword", "define"], " a ", ["string","'foo"], ["punctuation",")"]
 ]
 
 ----------------------------------------------------
 
-Checks for strings and symbols.
\ No newline at end of file
+Checks for strings and symbols.