diff --git a/compiler/raco.vim b/compiler/raco.vim new file mode 100644 index 0000000..d5d1d0f --- /dev/null +++ b/compiler/raco.vim @@ -0,0 +1,7 @@ +let current_compiler = 'raco' + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +CompilerSet makeprg=raco diff --git a/compiler/racomake.vim b/compiler/racomake.vim new file mode 100644 index 0000000..f542a33 --- /dev/null +++ b/compiler/racomake.vim @@ -0,0 +1,7 @@ +let current_compiler = 'racomake' + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +CompilerSet makeprg=raco\ make\ --\ % diff --git a/compiler/racotest.vim b/compiler/racotest.vim new file mode 100644 index 0000000..54cc796 --- /dev/null +++ b/compiler/racotest.vim @@ -0,0 +1,8 @@ +let current_compiler = 'racotest' + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +CompilerSet makeprg=raco\ test\ % +CompilerSet errorformat=location:%f:%l:%c diff --git a/ftdetect/racket.vim b/ftdetect/racket.vim index 07c9401..67c26df 100644 --- a/ftdetect/racket.vim +++ b/ftdetect/racket.vim @@ -1,6 +1,22 @@ -let g:racket_hash_lang_regexp = '^#lang\s\+\([^][)(}{[:space:]]\+\)' -let g:racket_hash_lang_dict = get(g:, 'racket_hash_lang_dict', - \ { +let g:racket_hash_lang_modifiers = + \ extend(get(g:, 'racket_hash_lang_modifiers', []), [ + \ 'at-exp', + \ 'errortrace', + \ 'pollen/mode', + \ ]) + +let g:racket_hash_lang_modifiers_regex = + \ get(g:, 'racket_hash_lang_modifiers_regex', + \ '\%('. + \ join(map(deepcopy(g:racket_hash_lang_modifiers), + \ {_, v -> printf('\<%s\>', escape(v, '\'))}), + \ '\|') + \ .'\)') + +let g:racket_hash_lang_regexp = get(g:, 'racket_hash_lang_regexp', + \ '^#lang\s\+\%\('.g:racket_hash_lang_modifiers_regex.'\s\+\)\?\([^][)(}{[:space:]]\+\)') +let g:racket_hash_lang_dict = + \ extend(get(g:, 'racket_hash_lang_dict', #{}), { \ 'racket/base': 'racket', \ 'racket/gui': 'racket', \ 'typed/racket': 'racket', @@ -9,7 +25,9 @@ let g:racket_hash_lang_dict = get(g:, 'racket_hash_lang_dict', \ 'br/quicklang': 'racket', \ 'scribble/base': 'scribble', \ 'scribble/manual': 'scribble', - \ }) + \ 'info': 'racket-info', + \ 'setup/infotab': 'racket-info', + \ }, 'keep') " keep prefers user dict to the default " Tries to detect filetype from #lang line; defaults to ft=racket. function! RacketDetectHashLang() diff --git a/ftplugin/jsond.vim b/ftplugin/jsond.vim new file mode 100644 index 0000000..53608da --- /dev/null +++ b/ftplugin/jsond.vim @@ -0,0 +1,22 @@ +" Language: jsond + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +" Enable auto begin new comment line when continuing from an old comment line +setl comments=:;;;;,:;;;,:;;,:; +setl formatoptions+=r + +"setl commentstring=;;%s +setl commentstring=#\|\ %s\ \|# + +let b:ale_linter_aliases = ['racket'] + +" Undo our settings when the filetype changes away from jsond +" (this should be amended if settings/mappings are added above!) +let b:undo_ftplugin = + \ "setl comments< formatoptions<" + \. "| setl commentstring<" + \. "| unlet b:ale_linter_aliases" diff --git a/ftplugin/racket-info.vim b/ftplugin/racket-info.vim new file mode 100644 index 0000000..8c17c9f --- /dev/null +++ b/ftplugin/racket-info.vim @@ -0,0 +1,60 @@ +" Language: info + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +" quick hack to allow adding values +setlocal iskeyword=@,!,#-',*-:,<-Z,a-z,~,_,94 + +" Enable auto begin new comment line when continuing from an old comment line +setl comments=:;;;;,:;;;,:;;,:; +setl formatoptions+=r + +" Simply setting keywordprg like this works: +" setl keywordprg=raco\ docs +" but then vim says: +" "press ENTER or type a command to continue" +" We avoid the annoyance of having to hit enter by remapping K directly. +function s:RacketDoc(word) abort + execute 'silent !raco docs --' shellescape(a:word) + redraw! +endfunction +nnoremap RacketDoc :call RacketDoc(expand('')) +if maparg("K", "n") == "" + nmap K RacketDoc +endif + +" For the visual mode K mapping, it's slightly more convoluted to get the +" selected text: +function! s:Racket_visual_doc() + try + let l:old_a = @a + normal! gv"ay + call system("raco docs '". @a . "'") + redraw! + return @a + finally + let @a = l:old_a + endtry +endfunction + +vnoremap RacketDoc :call Racket_visual_doc() +if maparg("K", "v") == "" + vmap K RacketDoc +endif + +"setl commentstring=;;%s +setl commentstring=#\|\ %s\ \|# + +let b:ale_linter_aliases = ['racket'] + +" Undo our settings when the filetype changes away from Racket +" (this should be amended if settings/mappings are added above!) +let b:undo_ftplugin = + \ "setl iskeyword< lispwords< lisp< comments< formatoptions<" + \. "| setl commentstring<" + \. "| nunmap K" + \. "| vunmap K" + \. "| unlet b:ale_linter_aliases" diff --git a/ftplugin/racket.vim b/ftplugin/racket.vim index a93ce5e..9e514bc 100644 --- a/ftplugin/racket.vim +++ b/ftplugin/racket.vim @@ -7,40 +7,23 @@ if exists("b:did_ftplugin") endif let b:did_ftplugin = 1 -setl iskeyword+=#,%,^ -setl lispwords+=module,module*,module+,parameterize,let-values,let*-values,letrec-values,local -setl lispwords+=define-values,opt-lambda,case-lambda,syntax-rules,with-syntax,syntax-case,syntax-parse -setl lispwords+=define-signature,unit,unit/sig,compund-unit/sig,define-values/invoke-unit/sig -setl lispwords+=define-opt/c,define-syntax-rule -setl lispwords+=struct - -" Racket OOP -setl lispwords+=class,define/public,define/private,define/override - -" kanren -setl lispwords+=fresh,run,run*,project,conde,condu - -" loops -setl lispwords+=for,for/list,for/fold,for*,for*/list,for*/fold,for/or,for/and -setl lispwords+=for/hash,for/sum,for/flvector,for*/flvector,for/vector - -setl lispwords+=match,match*,match/values,define/match,match-lambda,match-lambda*,match-lambda** -setl lispwords+=match-let,match-let*,match-let-values,match-let*-values -setl lispwords+=match-letrec,match-define,match-define-values -setl lisp +" quick hack to allow adding values +setlocal iskeyword=@,!,#-',*-:,<-Z,a-z,~,_,94 " Enable auto begin new comment line when continuing from an old comment line setl comments=:;;;;,:;;;,:;;,:; setl formatoptions+=r -setl makeprg=raco\ make\ --\ % - " Simply setting keywordprg like this works: " setl keywordprg=raco\ docs " but then vim says: " "press ENTER or type a command to continue" " We avoid the annoyance of having to hit enter by remapping K directly. -nnoremap RacketDoc :silent !raco docs :redraw! +function s:RacketDoc(word) abort + execute 'silent !raco docs --' shellescape(a:word) + redraw! +endfunction +nnoremap RacketDoc :call RacketDoc(expand('')) if maparg("K", "n") == "" nmap K RacketDoc endif @@ -67,10 +50,15 @@ endif "setl commentstring=;;%s setl commentstring=#\|\ %s\ \|# +if exists("loaded_matchit") && !exists("b:match_words") + let b:match_words = '#|:|#' +endif + " Undo our settings when the filetype changes away from Racket " (this should be amended if settings/mappings are added above!) let b:undo_ftplugin = \ "setl iskeyword< lispwords< lisp< comments< formatoptions<" - \. "| setl makeprg< commentstring<" + \. "| setl commentstring<" \. "| nunmap K" \. "| vunmap K" + \. "| unlet! b:match_words" diff --git a/indent/racket-info.vim b/indent/racket-info.vim new file mode 100644 index 0000000..b72d361 --- /dev/null +++ b/indent/racket-info.vim @@ -0,0 +1,9 @@ +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal lisp autoindent nosmartindent +setlocal lispwords=define + +let b:undo_indent = "setlocal lisp< ai< si< lw<" diff --git a/indent/racket.vim b/indent/racket.vim index 279e185..1f42a90 100644 --- a/indent/racket.vim +++ b/indent/racket.vim @@ -7,6 +7,33 @@ if exists("b:did_indent") endif let b:did_indent = 1 -setlocal ai nosi +setlocal lisp autoindent nosmartindent -let b:undo_indent = "setl ai< si<" +setlocal lispwords+=module,module*,module+,parameterize,let-values,let*-values,letrec-values,local +setlocal lispwords+=define/contract +setlocal lispwords+=λ +setlocal lispwords+=with-handlers +setlocal lispwords+=define-values,opt-lambda,case-lambda,syntax-rules,with-syntax,syntax-case,syntax-parse +setlocal lispwords+=define-for-syntax,define-syntax-parser,define-syntax-parse-rule,define-syntax-class,define-splicing-syntax-class +setlocal lispwords+=define-signature,unit,unit/sig,compund-unit/sig,define-values/invoke-unit/sig +setlocal lispwords+=define-opt/c,define-syntax-rule +setlocal lispwords+=define-test-suite +setlocal lispwords+=struct +setlocal lispwords+=with-input-from-file,with-output-to-file + +" Racket OOP +setlocal lispwords+=class,define/public,define/private,define/override + +" kanren +setlocal lispwords+=fresh,run,run*,project,conde,condu + +" loops +setlocal lispwords+=for,for/list,for/fold,for*,for*/list,for*/fold,for/or,for/and +setlocal lispwords+=for/hash,for/sum,for/flvector,for*/flvector,for/vector,for*/vector +setlocal lispwords+=for/async + +setlocal lispwords+=match,match*,match/values,define/match,match-lambda,match-lambda*,match-lambda** +setlocal lispwords+=match-let,match-let*,match-let-values,match-let*-values +setlocal lispwords+=match-letrec,match-define,match-define-values + +let b:undo_indent = "setlocal lisp< ai< si< lw<" diff --git a/syntax/jsond.vim b/syntax/jsond.vim new file mode 100644 index 0000000..a003073 --- /dev/null +++ b/syntax/jsond.vim @@ -0,0 +1,70 @@ +" Vim syntax file +" Language: #lang jsond + +if exists("b:current_syntax") + finish +endif + +" Hack: the syntax/json.vim file only permits numbers followed by blanks +" followed by some kind of object or array delimiter +" JSON the spec says a JSON is an element is a whitespace-delimited value, which +" can be any of an object, an array, a string, a number, or the keywords +" true/false/null +" Ref: https://www.json.org/json-en.html +syntax match jsonNumber "-\=\<\%(0\|[1-9]\d*\)\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\>" +syntax keyword jsonBoolean true false +syntax keyword jsonNull null + +syntax cluster json contains=jsonObject,jsonArray,jsonNumber,jsonStringMatch,jsonBoolean,jsonNull + +syntax region jsonArray matchgroup=jsonBraces start=/\[/ end=/]/ contains=@json fold +syntax region jsonObject matchgroup=jsonBraces start=/{/ end=/}/ contains=jsonKeyMatch fold + +syntax match jsonKeyMatch /"\([^"]\|\\\"\)\+"[[:blank:]\r\n]*:/ contains=jsonKey nextgroup=@json skipwhite +syntax region jsonKey start=/"/ end=/"\ze[[:blank:]\r\n]*:/ contained + +syntax match jsonStringMatch /"\([^"]\|\\\"\)\+"/ contains=jsonString +syntax region jsonString oneline start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=jsonEscape contained + +syntax match jsonEscape ,\\["\\/bfnrt], contained +syntax match jsonEscape /\\u\x\{4\}/ contained + +" syntax iskeyword 33,35-39,42-58,60-90,94,95,97-122,126,_ +" converted from decimal to char +" :s/\d\+/\=submatch(0)->str2nr()->nr2char()/g +" but corrected to remove duplicate _, move ^ to end +" also exclude comma, for JSON +syntax iskeyword @,!,#-',*-:,<-Z,a-z,~,_,^,,^ +" expanded +" syntax iskeyword !,#,$,%,&,',*,+,,,-,.,/,0-9,:,<,=,>,?,@,A-Z,_,a-z,~,^,,^ + +syntax match jsondSyntax "#lang " nextgroup=jsondLang +syntax keyword jsondLang jsond + +syntax keyword jsondName #:name nextgroup=jsondVarName skipwhite skipempty +syntax match jsondVarName ,\<\k\+\>, contained nextgroup=@json skipwhite skipempty + +" Comments +syntax match jsondComment /;.*$/ contains=jsondTodo,jsondNote,@Spell +syntax region jsondMultilineComment start=/#|/ end=/|#/ contains=jsondMultilineComment,jsondTodo,jsondNote,@Spell + +syntax keyword jsondTodo FIXME TODO XXX contained +syntax match jsondNote /\CNOTE\ze:\?/ contained + +highlight default link jsondSyntax Statement +highlight default link jsondName Type + +highlight default link jsondComment Comment +highlight default link jsondMultilineComment Comment + +highlight default link jsondTodo Todo +highlight default link jsondNote SpecialComment + +highlight default link jsonNumber Number +highlight default link jsonBoolean Boolean +highlight default link jsonNull Constant +highlight default link jsonString String +highlight default link jsonEscape Special +highlight default link jsonKey Label + +let b:current_syntax = "jsond" diff --git a/syntax/racket-info.vim b/syntax/racket-info.vim new file mode 100644 index 0000000..2d2cb0c --- /dev/null +++ b/syntax/racket-info.vim @@ -0,0 +1,206 @@ +" Vim syntax file +" Language: #lang info + +" Initializing: +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" Highlight unmatched parens +syntax match infoError ,[]})], + +syntax match fallbackError /./ + +if version < 600 + set iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_ +else + " syntax iskeyword 33,35-39,42-58,60-90,94,95,97-122,126,_ + " converted from decimal to char + " :s/\d\+/\=submatch(0)->str2nr()->nr2char()/g + " but corrected to remove duplicate _, move ^ to end + syntax iskeyword @,!,#-',*-:,<-Z,a-z,~,_,^ + " expanded + " syntax iskeyword !,#,$,%,&,',*,+,,,-,.,/,0-9,:,<,=,>,?,@,A-Z,_,a-z,~,^ +endif + +" https://docs.racket-lang.org/raco/info_rkt.html?q=info + +syntax keyword infoSyntax define quote quasiquote if + +syntax keyword infoPrimitive cons car cdr list list* reverse append equal? +syntax keyword infoPrimitive string-append make-immutable-hash hash hash-set +syntax keyword infoPrimitive hash-set* hash-remove hash-clear hash-update +syntax keyword infoPrimitive path->string build-path collection-path +syntax keyword infoPrimitive system-library-subpath getenv + +syntax match datumDelimiter !\<\.\>! + +syntax cluster infoTop contains=infoSyntax,infoPrimitive,datumDelimiter + +syntax match infoConstant ,\<\*\k\+\*\>, +syntax match infoConstant ,\<<\k\+>\>, + +" Non-quoted lists, and strings +syntax region infoStruc matchgroup=infoParen start="("rs=s+1 end=")"re=e-1 contains=@infoTop +syntax region infoStruc matchgroup=infoParen start="#("rs=s+2 end=")"re=e-1 contains=@infoTop +syntax region infoStruc matchgroup=infoParen start="{"rs=s+1 end="}"re=e-1 contains=@infoTop +syntax region infoStruc matchgroup=infoParen start="#{"rs=s+2 end="}"re=e-1 contains=@infoTop +syntax region infoStruc matchgroup=infoParen start="\["rs=s+1 end="\]"re=e-1 contains=@infoTop +syntax region infoStruc matchgroup=infoParen start="#\["rs=s+2 end="\]"re=e-1 contains=@infoTop + +for lit in ['hash', 'hasheq', 'hasheqv'] + execute printf('syntax match infoLit "\<%s\>" nextgroup=@infoParen containedin=ALLBUT,.*String,.*Comment', '#'.lit) +endfor + +for lit in ['rx', 'rx#', 'px', 'px#'] + execute printf('syntax match infoRe "\<%s\>" nextgroup=@infoString containedin=ALLBUT,.*String,.*Comment,', '#'.lit) +endfor + +unlet lit + +" Simple literals +syntax region infoString start=/\%(\\\)\@" +syntax match infoContainedNumberError "\<#b\k*[^-+01delfinas#./@]\>" +syntax match infoContainedNumberError "\<#[ei]#[ei]" +syntax match infoContainedNumberError "\<#[xdob]#[xdob]" + +" start with the simpler sorts +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\?\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\?\d\+/\d\+\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\?\d\+/\d\+[-+]\d\+\(/\d\+\)\?i\>" contains=infoContainedNumberError + +" different possible ways of expressing complex values +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?i\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\?\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?[-+]\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?i\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\(inf\|nan\)\.[0f][-+]\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?i\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\?\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?[-+]\(inf\|nan\)\.[0f]i\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\?\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?@[-+]\?\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\(inf\|nan\)\.[0f]@[-+]\?\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[dobie]\)\{0,2}[-+]\?\(\d\+\|\d\+#*\.\|\d*\.\d\+\)#*\(/\d\+#*\)\?\([sdlef][-+]\?\d\+#*\)\?@[-+]\(inf\|nan\)\.[0f]\>" contains=infoContainedNumberError + +" hex versions of the above (separate because of the different possible exponent markers) +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\?\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\?\x\+/\x\+\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\?\x\+/\x\+[-+]\x\+\(/\x\+\)\?i\>" + +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?i\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\?\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?[-+]\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?i\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\(inf\|nan\)\.[0f][-+]\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?i\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\?\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?[-+]\(inf\|nan\)\.[0f]i\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\?\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?@[-+]\?\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\(inf\|nan\)\.[0f]@[-+]\?\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?\>" +syntax match infoNumber "\<\(#x\|#[ei]#x\|#x#[ei]\)[-+]\?\(\x\+\|\x\+#*\.\|\x*\.\x\+\)#*\(/\x\+#*\)\?\([sl][-+]\?\x\+#*\)\?@[-+]\(inf\|nan\)\.[0f]\>" + +" these work for any radix +syntax match infoNumber "\<\(#[xdobie]\)\{0,2}[-+]\(inf\|nan\)\.[0f]i\?\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[xdobie]\)\{0,2}[-+]\(inf\|nan\)\.[0f][-+]\(inf\|nan\)\.[0f]i\>" contains=infoContainedNumberError +syntax match infoNumber "\<\(#[xdobie]\)\{0,2}[-+]\(inf\|nan\)\.[0f]@[-+]\(inf\|nan\)\.[0f]\>" contains=infoContainedNumberError + +syntax keyword infoBoolean #t #f #true #false #T #F + +syntax match infoError "\<#\\\k*\>" + +syntax match infoChar "\<#\\.\w\@!" +syntax match infoChar "\<#\\space\>" +syntax match infoChar "\<#\\newline\>" +syntax match infoChar "\<#\\return\>" +syntax match infoChar "\<#\\null\?\>" +syntax match infoChar "\<#\\backspace\>" +syntax match infoChar "\<#\\tab\>" +syntax match infoChar "\<#\\linefeed\>" +syntax match infoChar "\<#\\vtab\>" +syntax match infoChar "\<#\\page\>" +syntax match infoChar "\<#\\rubout\>" +syntax match infoChar "\<#\\\o\{1,3}\>" +syntax match infoChar "\<#\\x\x\{1,2}\>" +syntax match infoChar "\<#\\u\x\{1,6}\>" + +syntax cluster infoTop add=infoNumber,infoBoolean,infoChar + +syntax match infoSyntax "#lang " nextgroup=infoLang +syntax keyword infoLang info setup/infotab +syntax match infoExtSyntax "#:\k\+" + +syntax cluster infoTop add=infoExtFunc,infoExtSyntax + +" syntax quoting, unquoting and quasiquotation +syntax match infoQuote "#\?['`]" + +syntax match infoUnquote "#," +syntax match infoUnquote "#,@" +syntax match infoUnquote "," +syntax match infoUnquote ",@" + +" Comments +syntax match infoComment /;.*$/ contains=infoTodo,infoNote,@Spell +syntax region infoMultilineComment start=/#|/ end=/|#/ contains=infoMultilineComment,infoTodo,infoNote,@Spell +syntax match infoFormComment "#;" nextgroup=@infoTop + +syntax keyword infoTodo FIXME TODO XXX contained +syntax match infoNote /\CNOTE\ze:\?/ contained + +syntax cluster infoTop add=infoQuote,infoUnquote,infoComment,infoMultilineComment,infoFormComment + +" Synchronization and the wrapping up... +syntax sync match matchPlace grouphere NONE "^[^ \t]" +" ... i.e. synchronize on a line that starts at the left margin + +" Define the default highlighting. +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_info_syntax_inits") + if version < 508 + let did_info_syntax_inits = 1 + command -nargs=+ HiLink highlight link + else + command -nargs=+ HiLink highlight def link + endif + + HiLink infoSyntax Statement + HiLink infoPrimitive Function + + HiLink infoString String + HiLink infoChar Character + HiLink infoBoolean Boolean + + HiLink infoNumber Number + HiLink infoNumberError Error + HiLink infoContainedNumberError Error + + HiLink infoQuote SpecialChar + HiLink infoUnquote SpecialChar + + HiLink datumDelimiter Delimiter + HiLink infoParen Delimiter + HiLink infoConstant Constant + + HiLink infoLit Type + HiLink infoRe Type + + HiLink infoComment Comment + HiLink infoMultilineComment Comment + HiLink infoFormComment SpecialChar + HiLink infoTodo Todo + HiLink infoNote SpecialComment + HiLink infoError Error + HiLink fallbackError Error + + HiLink infoExtSyntax Type + HiLink infoExtFunc PreProc + delcommand HiLink +endif + +let b:current_syntax = "racket-info" diff --git a/syntax/racket.vim b/syntax/racket.vim index aae6723..e82d75b 100644 --- a/syntax/racket.vim +++ b/syntax/racket.vim @@ -11,15 +11,19 @@ elseif exists("b:current_syntax") finish endif -syn case ignore - " Highlight unmatched parens syn match racketError ,[]})], if version < 600 set iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_ else - setlocal iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_ + " syntax iskeyword 33,35-39,42-58,60-90,94,95,97-122,126,_ + " converted from decimal to char + " :s/\d\+/\=submatch(0)->str2nr()->nr2char()/g + " but corrected to remove duplicate _, move ^ to end + syntax iskeyword @,!,#-',*-:,<-Z,a-z,~,_,^ + " expanded + " syntax iskeyword !,#,$,%,&,',*,+,,,-,.,/,0-9,:,<,=,>,?,@,A-Z,_,a-z,~,^ endif " Forms in order of appearance at @@ -213,7 +217,7 @@ syn keyword racketFunc locale-string-encoding syn keyword racketFunc char? char->integer integer->char syn keyword racketFunc char=? char? char>=? syn keyword racketFunc char-ci=? char-ci? char-ci>=? -syn keyword racketFunc char-alphabetic? char-lowercase? char-uppercase? char-title-case? +syn keyword racketFunc char-alphabetic? char-lower-case? char-upper-case? char-title-case? syn keyword racketFunc char-numeric? char-symbolic? char-punctuation? char-graphic? syn keyword racketFunc char-whitespace? char-blank? syn keyword racketFunc char-iso-control? char-general-category @@ -470,38 +474,34 @@ syn keyword racketFunc seconds->date current-milliseconds syn match racketDelimiter !\<\.\>! -syn match racketSymbol ,\k+, contained - -syn cluster racketNormal contains=racketSyntax,racketFunc,racketDelimiter -syn cluster racketQuotedStuff contains=racketSymbol -syn cluster racketQuotedOrNormal contains=racketDelimiter +syn cluster racketTop contains=racketSyntax,racketFunc,racketDelimiter syn match racketConstant ,\<\*\k\+\*\>, syn match racketConstant ,\<<\k\+>\>, -syn region racketQuotedStruc start="("rs=s+1 end=")"re=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal contained -syn region racketQuotedStruc start="#("rs=s+2 end=")"re=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal contained -syn region racketQuotedStruc start="{"rs=s+1 end="}"re=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal contained -syn region racketQuotedStruc start="#{"rs=s+2 end="}"re=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal contained -syn region racketQuotedStruc start="\["rs=s+1 end="\]"re=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal contained -syn region racketQuotedStruc start="#\["rs=s+2 end="\]"re=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal contained +" Non-quoted lists, and strings +syn region racketStruc matchgroup=racketParen start="("rs=s+1 end=")"re=e-1 contains=@racketTop +syn region racketStruc matchgroup=racketParen start="#("rs=s+2 end=")"re=e-1 contains=@racketTop +syn region racketStruc matchgroup=racketParen start="{"rs=s+1 end="}"re=e-1 contains=@racketTop +syn region racketStruc matchgroup=racketParen start="#{"rs=s+2 end="}"re=e-1 contains=@racketTop +syn region racketStruc matchgroup=racketParen start="\["rs=s+1 end="\]"re=e-1 contains=@racketTop +syn region racketStruc matchgroup=racketParen start="#\["rs=s+2 end="\]"re=e-1 contains=@racketTop -syn cluster racketQuotedStuff add=racketQuotedStruc +for lit in ['hash', 'hasheq', 'hasheqv'] + execute printf('syntax match racketLit "\<%s\>" nextgroup=@racketParen containedin=ALLBUT,.*String,.*Comment', '#'.lit) +endfor -" Non-quoted lists, and strings -syn region racketStruc matchgroup=Delimiter start="("rs=s+1 matchgroup=Delimiter end=")"re=e-1 contains=@racketNormal -syn region racketStruc matchgroup=Delimiter start="#("rs=s+2 matchgroup=Delimiter end=")"re=e-1 contains=@racketNormal -syn region racketStruc matchgroup=Delimiter start="{"rs=s+1 matchgroup=Delimiter end="}"re=e-1 contains=@racketNormal -syn region racketStruc matchgroup=Delimiter start="#{"rs=s+2 matchgroup=Delimiter end="}"re=e-1 contains=@racketNormal -syn region racketStruc matchgroup=Delimiter start="\["rs=s+1 matchgroup=Delimiter end="\]"re=e-1 contains=@racketNormal -syn region racketStruc matchgroup=Delimiter start="#\["rs=s+2 matchgroup=Delimiter end="\]"re=e-1 contains=@racketNormal +for lit in ['rx', 'rx#', 'px', 'px#'] + execute printf('syntax match racketRe "\<%s\>" nextgroup=@racketString containedin=ALLBUT,.*String,.*Comment,', '#'.lit) +endfor + +unlet lit " Simple literals syn region racketString start=/\%(\\\)\@" syn match racketChar "\<#\\vtab\>" syn match racketChar "\<#\\page\>" syn match racketChar "\<#\\rubout\>" -syn match racketChar "\<#\\[0-7]\{1,3}\>" -syn match racketChar "\<#\\x[0-9a-f]\{1,2}\>" -syn match racketChar "\<#\\u[0-9a-f]\{1,6}\>" +syn match racketChar "\<#\\\o\{1,3}\>" +syn match racketChar "\<#\\x\x\{1,2}\>" +syn match racketChar "\<#\\u\x\{1,6}\>" -syn cluster racketNormal add=racketNumber,racketBoolean,racketChar -syn cluster racketQuotedOrNormal add=racketNumber,racketBoolean +syn cluster racketTop add=racketNumber,racketBoolean,racketChar " Command-line parsing syn keyword racketExtFunc command-line current-command-line-arguments once-any help-labels multi once-each @@ -574,45 +573,26 @@ syn keyword racketExtFunc command-line current-command-line-arguments once-any h syn match racketSyntax "#lang " syn match racketExtSyntax "#:\k\+" -syn cluster racketNormal add=racketExtFunc,racketExtSyntax +syn cluster racketTop add=racketExtFunc,racketExtSyntax " syntax quoting, unquoting and quasiquotation -syn region racketQuoted matchgroup=Delimiter start="['`]" end=![ \t()\[\]";]!me=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal -syn region racketQuoted matchgroup=Delimiter start="['`](" matchgroup=Delimiter end=")" contains=@racketQuotedStuff,@racketQuotedOrNormal -syn region racketQuoted matchgroup=Delimiter start="['`]\?#(" matchgroup=Delimiter end=")" contains=@racketQuotedStuff,@racketQuotedOrNormal - -syn region racketUnquote matchgroup=Delimiter start="#,"rs=s+2 end=![ \t\[\]()";]!re=e-1,me=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start="#,@"rs=s+3 end=![ \t\[\]()";]!re=e-1,me=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start="#,("rs=s+3 end=")"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start="#,@("rs=s+4 end=")"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start="#,\["rs=s+3 end="\]"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start="#,@\["rs=s+4 end="\]"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=","rs=s+1 end=![ \t\[\]()";]!re=e-1,me=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",@"rs=s+2 end=![ \t\[\]()";]!re=e-1,me=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",("rs=s+2 end=")"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",@("rs=s+3 end=")"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",#("rs=s+3 end=")"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",@#("rs=s+4 end=")"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",\["rs=s+2 end="\]"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",@\["rs=s+3 end="\]"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",#\["rs=s+3 end="\]"re=e-1 contained contains=@racketNormal -syn region racketUnquote matchgroup=Delimiter start=",@#\["rs=s+4 end="\]"re=e-1 contained contains=@racketNormal - -syn cluster racketQuotedStuff add=racketUnquote - -syn region racketQuoted matchgroup=Delimiter start="#['`]"rs=s+2 end=![ \t()\[\]";]!re=e-1,me=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal -syn region racketQuoted matchgroup=Delimiter start="#['`]("rs=s+3 matchgroup=Delimiter end=")"re=e-1 contains=@racketQuotedStuff,@racketQuotedOrNormal +syn match racketQuote "#\?['`]" + +syn match racketUnquote "#," +syn match racketUnquote "#,@" +syn match racketUnquote "," +syn match racketUnquote ",@" " Comments +syn match racketSharpBang "\%^#![ /].*" display syn match racketComment /;.*$/ contains=racketTodo,racketNote,@Spell syn region racketMultilineComment start=/#|/ end=/|#/ contains=racketMultilineComment,racketTodo,racketNote,@Spell +syn match racketFormComment "#;" nextgroup=@racketTop -syn keyword racketTodo FIXME TODO XXX contained +syn match racketTodo /\C\<\(FIXME\|TODO\|XXX\)\ze:\?\>/ contained syntax match racketNote /\CNOTE\ze:\?/ contained -syn cluster racketNormal add=racketQuoted,racketComment,racketMultilineComment -syn cluster racketQuotedOrNormal add=racketComment,racketMultilineComment - +syn cluster racketTop add=racketQuote,racketUnquote,racketComment,racketMultilineComment,racketFormComment " Synchronization and the wrapping up... syn sync match matchPlace grouphere NONE "^[^ \t]" @@ -640,15 +620,20 @@ if version >= 508 || !exists("did_racket_syntax_inits") HiLink racketNumberError Error HiLink racketContainedNumberError Error - HiLink racketQuoted Structure - HiLink racketQuotedStruc Structure - HiLink racketSymbol Structure + HiLink racketQuote SpecialChar + HiLink racketUnquote SpecialChar HiLink racketDelimiter Delimiter + HiLink racketParen Delimiter HiLink racketConstant Constant + HiLink racketLit Type + HiLink racketRe Type + HiLink racketComment Comment HiLink racketMultilineComment Comment + HiLink racketFormComment SpecialChar + HiLink racketSharpBang Comment HiLink racketTodo Todo HiLink racketNote SpecialComment HiLink racketError Error diff --git a/test/at-exp.rkt b/test/at-exp.rkt new file mode 100644 index 0000000..9f98a78 --- /dev/null +++ b/test/at-exp.rkt @@ -0,0 +1,9 @@ +#lang at-exp racket + +(define (bar) + "BAR") + +(define (foo) + (displayln @~a{Foo is a @(bar)})) + +(foo) diff --git a/test/pollen-mode.rkt b/test/pollen-mode.rkt new file mode 100644 index 0000000..3017055 --- /dev/null +++ b/test/pollen-mode.rkt @@ -0,0 +1,9 @@ +#lang pollen/mode racket + +(define (bar) + "BAR") + +(define (foo) + (displayln ◊~a{Foo is a ◊(bar)})) + +(foo)