서브라임이 구문분석을 할 수 있게 하기위해, Scheme.tmLanguage 파일을 생성한다. (경로는 main.sublime-menu 에 지정되어 있다. 기본값은 다음과 같음)
Packages\sublime-scheme-syntax\Scheme.tmLanguage
comment
The foldings do not currently work the way I want them to. This
may be a limitation of the way they are applied rather than the
regexps in use. Nonetheless, the foldings will end on the last
identically indented blank line following an s-expression. Not
ideal perhaps, but it works. Also, the #illegal pattern never
matches an unpaired ( as being illegal. Why?! -- Rob Rix
Ok, hopefully this grammar works better on quoted stuff now. It
may break for fancy macros, but should generally work pretty
smoothly. -- Jacob Rus
I have attempted to get this under control but because of the way folding
and indentation interact in Textmate, I am not sure if it is possible. In the
meantime, I have implemented Python-style folding anchored at newlines.
Additionally, I have made some minor improvements to the numeric constant
highlighting. Next up is square bracket expressions, I guess, but that
should be trivial. -- ozy`
fileTypesscmschfoldingStartMarker(?x)^ [ \t]* \(
(?<par>
( [^()\n]++ | \( \g<par> \)? )*+
)
$foldingStopMarker^\s*$keyEquivalent^~SnameSchemepatternsinclude#commentinclude#sexpinclude#stringinclude#language-functionsinclude#quoteinclude#illegalinclude#constantsrepositorycommentcaptures1namepunctuation.definition.comment.schemematch(;).*$\n?namecomment.line.semicolon.schemeconstantspatternsmatch#[t|f]nameconstant.language.boolean.schemematch(?<=[\(\s])((#e|#i)?[0-9]+(\.[0-9]+)?|(#x)[0-9a-fA-F]+|(#o)[0-7]+|(#b)[01]+)(?=[\s;()'",\[\]])nameconstant.numeric.schemeillegalmatch[()\[\]]nameinvalid.illegal.parenthesis.schemelanguage-functionspatternsmatch(?x)
(?<=(\s|\(|\[)) # preceded by space or (
( do|or|and|else|quasiquote|begin|if|case|set!|
cond|let|unquote|define|let\*|unquote-splicing|delay|
letrec)
(?=(\s|\())namekeyword.control.schemecomment
These functions run a test, and return a boolean
answer.
match(?x)
(?<=(\s|\()) # preceded by space or (
( char-alphabetic|char-lower-case|char-numeric|
char-ready|char-upper-case|char-whitespace|
(?:char|string)(?:-ci)?(?:=|<=?|>=?)|
atom|boolean|bound-identifier=|char|complex|
identifier|integer|symbol|free-identifier=|inexact|
eof-object|exact|list|(?:input|output)-port|pair|
real|rational|zero|vector|negative|odd|null|string|
eq|equal|eqv|even|number|positive|procedure
)
(\?) # name ends with ? sign
(?=(\s|\()) # followed by space or (
namesupport.function.boolean-test.schemecomment
These functions change one type into another.
match(?x)
(?<=(\s|\()) # preceded by space or (
( char->integer|exact->inexact|inexact->exact|
integer->char|symbol->string|list->vector|
list->string|identifier->symbol|vector->list|
string->list|string->number|string->symbol|
number->string
)
(?=(\s|\()) # followed by space or (
namesupport.function.convert-type.schemecomment
These functions are potentially dangerous because
they have side-effects which could affect other
parts of the program.
match(?x)
(?<=(\s|\()) # preceded by space or (
( set-(?:car|cdr)| # set car/cdr
(?:vector|string)-(?:fill|set) # fill/set string/vector
)
(!) # name ends with ! sign
(?=(\s|\()) # followed by space or (
namesupport.function.with-side-effects.schemecomment
+, -, *, /, =, >, etc.
match(?x)
(?<=(\s|\()) # preceded by space or (
( >=?|<=?|=|[*/+-])
(?=(\s|\()) # followed by space or (
namekeyword.operator.arithmetic.schemematch(?x)
(?<=(\s|\()) # preceded by space or (
( append|apply|approximate|
call-with-current-continuation|call/cc|catch|
construct-identifier|define-syntax|display|foo|
for-each|force|cd|gen-counter|gen-loser|
generate-identifier|last-pair|length|let-syntax|
letrec-syntax|list|list-ref|list-tail|load|log|
macro|magnitude|map|map-streams|max|member|memq|
memv|min|newline|nil|not|peek-char|rationalize|
read|read-char|return|reverse|sequence|substring|
syntax|syntax-rules|transcript-off|transcript-on|
truncate|unwrap-syntax|values-list|write|write-char|
# cons, car, cdr, etc
cons|c(a|d){1,4}r|
# unary math operators
abs|acos|angle|asin|assoc|assq|assv|atan|ceiling|
cos|floor|round|sin|sqrt|tan|
(?:real|imag)-part|numerator|denominator
# other math operators
modulo|exp|expt|remainder|quotient|lcm|
# ports / files
call-with-(?:input|output)-file|
(?:close|current)-(?:input|output)-port|
with-(?:input|output)-from-file|
open-(?:input|output)-file|
# char-«foo»
char-(?:downcase|upcase|ready)|
# make-«foo»
make-(?:polar|promise|rectangular|string|vector)
# string-«foo», vector-«foo»
string(?:-(?:append|copy|length|ref))?|
vector(?:-length|-ref)
)
(?=(\s|\()) # followed by space or (
namesupport.function.general.schemequotecomment
We need to be able to quote any kind of item, which creates
a tiny bit of complexity in our grammar. It is hopefully
not overwhelming complexity.
Note: the first two matches are special cases. quoted
symbols, and quoted empty lists are considered constant.other
patternscaptures1namepunctuation.section.quoted.symbol.schemematch(?x)
(')\s*
([[:alnum:]][[:alnum:]!$%&*+-./:<=>?@^_~]*)
nameconstant.other.symbol.schemecaptures1namepunctuation.section.quoted.empty-list.scheme2namemeta.expression.scheme3namepunctuation.section.expression.begin.scheme4namepunctuation.section.expression.end.schemematch(?x)
(')\s*
((\()\s*(\)))
nameconstant.other.empty-list.schembegin(')\s*beginCaptures1namepunctuation.section.quoted.schemecommentquoted double-quoted string or s-expressionend(?=[\s()])|(?<=\n)namestring.other.quoted-object.schemepatternsinclude#quotedquote-sexpbegin(?<=\()\s*(quote)\b\s*beginCaptures1namekeyword.control.quote.schemecomment
Something quoted with (quote «thing»). In this case «thing»
will not be evaluated, so we are considering it a string.
contentNamestring.other.quote.schemeend(?=[\s)])|(?<=\n)patternsinclude#quotedquotedpatternsinclude#stringbegin(\()beginCaptures1namepunctuation.section.expression.begin.schemeend(\))endCaptures1namepunctuation.section.expression.end.schemenamemeta.expression.schemepatternsinclude#quotedinclude#quoteinclude#illegalsexpbegin(\()beginCaptures1namepunctuation.section.expression.begin.schemeend(\))(\n)?endCaptures1namepunctuation.section.expression.end.scheme2namemeta.after-expression.schemenamemeta.expression.schemepatternsinclude#commentinclude#constantsbegin(?x)
(?<=\() # preceded by (
(define)\s+ # define
(\() # list of parameters
([[:alnum:]][[:alnum:]!$%&*+-./:<=>?@^_~]*)
((\s+
([[:alnum:]][[:alnum:]!$%&*+-./:<=>?@^_~]*|[._])
)*
)\s*
(\))
captures1namekeyword.control.scheme2namepunctuation.definition.function.scheme3nameentity.name.function.scheme4namevariable.parameter.function.scheme7namepunctuation.definition.function.schemeend(?=\))namemeta.declaration.procedure.schemepatternsinclude#commentinclude#constantsinclude#sexpinclude#illegalbegin(?x)
(?<=\() # preceded by (
(lambda)\s+
(\() # opening paren
((?:
([[:alnum:]][[:alnum:]!$%&*+-./:<=>?@^_~]*|[._])
\s+
)*(?:
([[:alnum:]][[:alnum:]!$%&*+-./:<=>?@^_~]*|[._])
)?)
(\)) # closing paren
captures1namekeyword.control.scheme2namepunctuation.definition.variable.scheme3namevariable.parameter.scheme6namepunctuation.definition.variable.schemecomment
Not sure this one is quite correct. That \s* is
particularly troubling
end(?=\))namemeta.declaration.procedure.schemepatternsinclude#commentinclude#constantsinclude#sexpinclude#illegalbegin(?<=\()(define)\s([[:alnum:]][[:alnum:]!$%&*+-./:<=>?@^_~]*)\s*.*?captures1namekeyword.control.scheme2namevariable.other.schemeend(?=\))namemeta.declaration.variable.schemepatternsinclude#commentinclude#constantsinclude#sexpinclude#illegalinclude#quote-sexpinclude#quoteinclude#language-functionsinclude#stringinclude#constantsmatch(?<=[\(\s])(#\\)(space|newline|tab)(?=[\s\)])nameconstant.character.named.schemematch(?<=[\(\s])(#\\)x[0-9A-F]{2,4}(?=[\s\)])nameconstant.character.hex-literal.schemematch(?<=[\(\s])(#\\).(?=[\s\)])nameconstant.character.escape.schemecomment
the . in (a . b) which conses together two elements
a and b. (a b c) == (a . (b . (c . nil)))
match(?<=[ ()])\.(?=[ ()])namepunctuation.separator.cons.schemeinclude#sexpinclude#illegalstringbegin(")beginCaptures1namepunctuation.definition.string.begin.schemeend(")endCaptures1namepunctuation.definition.string.end.schemenamestring.quoted.double.schemepatternsmatch\\.nameconstant.character.escape.schemescopeNamesource.schemeuuid3EC2CFD0-909C-4692-AC29-1A60ADBC161E