Easier way to define new languages

Add more test cases

Also fixed some style issues

TODO: split tests up in multiple files, e.g. test/test_html_syntax.vader
This commit is contained in:
Adriaan Zonnenberg
2017-03-23 00:10:59 +01:00
parent 82067c7d14
commit 32d2c0a943
4 changed files with 181 additions and 90 deletions

View File

@@ -6,89 +6,57 @@ if exists("b:current_syntax")
finish finish
endif endif
if !exists("s:syntaxes") ""
" Search available syntax files. " Get the pattern for a HTML {name} attribute with {value}.
function s:search_syntaxes(...) function! s:attr(name, value)
let syntaxes = {} return a:name . '=\("\|''\)[^\1]*' . a:value . '[^\1]*\1'
let names = a:000 endfunction
for name in names
let syntaxes[name] = 0
endfor
for path in split(&runtimepath, ',') ""
if isdirectory(path . '/syntax') " Check whether a syntax file for a given {language} exists.
for name in names function! s:syntax_available(language)
let syntaxes[name] = syntaxes[name] || filereadable(path . '/syntax/' . name . '.vim') return !empty(globpath(&runtimepath, 'syntax/' . a:language . '.vim'))
endfor endfunction
endif
endfor
return syntaxes
endfunction
let s:syntaxes = s:search_syntaxes('pug', 'slm', 'coffee', 'stylus', 'sass', 'scss', 'less', 'typescript') ""
endif " Register {language} for a given {tag}.
" If [omit_attr] is 1, the 'lang' attribute may be omitted.
" If [attr_override] is given and not empty, it will be used for the attribute pattern.
function! s:register_language(language, tag, ...)
let omit_attr = a:0 ? a:1 : 0
let attr_override = a:0 >= 2 ? a:2 : ''
if omit_attr
let start_pattern = ''
else
let start_pattern = ' \_[^>]*'
let start_pattern .= !empty(attr_override) ? attr_override : s:attr('lang', a:language)
endif
syntax include @HTML syntax/html.vim if s:syntax_available(a:language)
unlet! b:current_syntax execute 'syntax include @' . a:language . ' syntax/' . a:language . '.vim'
syntax region html keepend start=/^<template\_[^>]*>/ end=/^<\/template>/ contains=@HTML fold unlet! b:current_syntax
execute 'syntax region vue_' . a:language
\ 'keepend'
\ 'matchgroup=Delimiter'
\ 'start=/^<' . a:tag . start_pattern . '\_[^>]*>/'
\ 'end="^</' . a:tag . '>"'
\ 'contains=@' . a:language
\ 'fold'
endif
endfunction
if s:syntaxes.pug call s:register_language('html', 'template', 1)
syntax include @PUG syntax/pug.vim call s:register_language('pug', 'template', 0, s:attr('lang', '\%(pug\|jade\)'))
unlet! b:current_syntax call s:register_language('slm', 'template')
syntax region pug keepend start=/<template lang=\("\|'\)[^\1]*pug[^\1]*\1>/ end="</template>" contains=@PUG fold call s:register_language('handlebars', 'template')
syntax region pug keepend start=/<template lang=\("\|'\)[^\1]*jade[^\1]*\1>/ end="</template>" contains=@PUG fold call s:register_language('javascript', 'script', 1)
endif call s:register_language('typescript', 'script', 0, '\%(lang=\("\|''\)[^\1]*\(ts\|typescript\)[^\1]*\1\|ts\)')
call s:register_language('coffee', 'script')
if s:syntaxes.slm call s:register_language('css', 'style', 1)
syntax include @SLM syntax/slm.vim call s:register_language('stylus', 'style')
unlet! b:current_syntax call s:register_language('sass', 'style')
syntax region slm keepend start=/<template lang=\("\|'\)[^\1]*slm[^\1]*\1>/ end="</template>" contains=@SLM fold call s:register_language('scss', 'style')
endif call s:register_language('less', 'style')
syntax include @JS syntax/javascript.vim
unlet! b:current_syntax
syntax region javascript keepend matchgroup=Delimiter start=/<script\( lang="babel"\)\?\( type="text\/babel"\)\?>/ end="</script>" contains=@JS fold
if s:syntaxes.typescript
syntax include @TS syntax/typescript.vim
unlet! b:current_syntax
syntax region typescript keepend matchgroup=Delimiter start=/<script \_[^>]*\(lang=\("\|'\)[^\2]*\(ts\|typescript\)[^\2]*\2\|ts\)\_[^>]*>/ end="</script>" contains=@TS fold
endif
if s:syntaxes.coffee
syntax include @COFFEE syntax/coffee.vim
unlet! b:current_syntax
" Matchgroup seems to be necessary for coffee
syntax region coffee keepend matchgroup=Delimiter start="<script lang=\"coffee\">" end="</script>" contains=@COFFEE fold
endif
syntax include @CSS syntax/css.vim
unlet! b:current_syntax
syntax region css keepend start=/<style\_[^>]*>/ end="</style>" contains=@CSS fold
if s:syntaxes.stylus
syntax include @stylus syntax/stylus.vim
unlet! b:current_syntax
syntax region stylus keepend start=/<style \_[^>]*lang=\("\|'\)[^\1]*stylus[^\1]*\1\_[^>]*>/ end="</style>" contains=@stylus fold
endif
if s:syntaxes.sass
syntax include @sass syntax/sass.vim
unlet! b:current_syntax
syntax region sass keepend start=/<style \_[^>]*lang=\("\|'\)[^\1]*sass[^\1]*\1\_[^>]*>/ end="</style>" contains=@sass fold
endif
if s:syntaxes.scss
syntax include @scss syntax/scss.vim
unlet! b:current_syntax
syntax region scss keepend start=/<style \_[^>]*lang=\("\|'\)[^\1]*scss[^\1]*\1\_[^>]*>/ end="</style>" contains=@scss fold
endif
if s:syntaxes.less
syntax include @less syntax/less.vim
unlet! b:current_syntax
syntax region less keepend matchgroup=PreProc start=/<style \_[^>]*lang=\("\|'\)[^\1]*less[^\1]*\1\_[^>]*>/ end="</style>" contains=@less fold
endif
let b:current_syntax = "vue" let b:current_syntax = "vue"

View File

@@ -8,6 +8,7 @@ repos=(
'digitaltoad/vim-pug' 'digitaltoad/vim-pug'
'groenewege/vim-less' 'groenewege/vim-less'
'kchmck/vim-coffee-script' 'kchmck/vim-coffee-script'
'leafgarland/typescript-vim'
'slm-lang/vim-slm' 'slm-lang/vim-slm'
'wavded/vim-stylus' 'wavded/vim-stylus'
) )

View File

@@ -1,7 +1,7 @@
# #
# HTML # HTML
# #
Given vue(An unindented html template): Given vue (An unindented html template):
<template> <template>
<div> <div>
Hello Hello
@@ -21,7 +21,7 @@ Expect (The html template got indented):
# #
# JavaScript # JavaScript
# #
Given vue(An unindented JavaScript region): Given vue (An unindented JavaScript region):
<script> <script>
export default { export default {
methods: { methods: {
@@ -35,7 +35,7 @@ Given vue(An unindented JavaScript region):
Do (Indent the whole buffer): Do (Indent the whole buffer):
gg=G gg=G
Expect vue(TODO): Expect vue (TODO):
* TODO: fix the indent script to exclude the surrounding html tag * TODO: fix the indent script to exclude the surrounding html tag
<script> <script>
export default { export default {
@@ -50,7 +50,7 @@ Expect vue(TODO):
# #
# CSS # CSS
# #
Given vue(An unindented css region): Given vue (An unindented css region):
<style> <style>
body { body {
background: tomato; background: tomato;
@@ -60,7 +60,7 @@ Given vue(An unindented css region):
Do: Do:
gg=G gg=G
Expect vue(The css region got indented): Expect vue (The css region got indented):
<style> <style>
body { body {
background: tomato; background: tomato;

View File

@@ -1,7 +1,7 @@
# #
# HTML # HTML
# #
Given vue(HTML template without lang attribute): Given vue (HTML template without lang attribute):
<template> <template>
<div></div> <div></div>
</template> </template>
@@ -9,26 +9,148 @@ Given vue(HTML template without lang attribute):
Execute: Execute:
AssertEqual 'htmlTag', SyntaxAt(2, 3) AssertEqual 'htmlTag', SyntaxAt(2, 3)
Given vue (Template tag inside a template):
<template>
<div>
<template v-if="loading">
Loading...
</template>
</div>
</template>
Execute (Syntax doesn't stop at the first closing template tag):
AssertEqual 'htmlEndTag', SyntaxAt(6, 3)
# #
# JavaScript # JavaScript
# #
Given vue: Given vue:
<script> <script>
// //
</script> </script>
Execute: Execute:
AssertEqual 'javaScriptLineComment', SyntaxAt(2, 3) AssertEqual 'javaScriptLineComment', SyntaxAt(2, 1)
" TODO: Assert that the script tag is highlighted as HTML " TODO: Assert that the script tag is highlighted as HTML
Given vue (Script tag with misc. attributes and newline):
<script type="text/babel"
lang="babel"
>
//
</script>
Execute:
AssertEqual 'javaScriptLineComment', SyntaxAt(4, 1)
# #
# CSS # CSS
# #
Given vue(CSS region without lang attribute): Given vue (CSS region without lang attribute):
<style> <style>
/**/ /**/
</style> </style>
Execute: Execute:
AssertEqual 'cssComment', SyntaxAt(2, 3) AssertEqual 'cssComment', SyntaxAt(2, 1)
" TODO Assert that the style tag is highlighted as HTML " TODO Assert that the style tag is highlighted as HTML
#
# Pug
#
Given vue (Pug template):
<template lang="pug">
p #{name}'s Pug source code!
</template>
Execute:
AssertEqual 'htmlTagName', SyntaxAt(2, 1)
AssertEqual 'pugInterpolationDelimiter', SyntaxAt(2, 3)
Given vue (Pug template using their former name):
<template lang="jade">
p #{name}'s Pug source code!
</template>
Execute:
AssertEqual 'htmlTagName', SyntaxAt(2, 1)
AssertEqual 'pugInterpolationDelimiter', SyntaxAt(2, 3)
#
# SCSS
#
Given vue (SCSS region):
<style lang="scss">
$green: #42b983;
</style>
Execute:
AssertEqual 'scssVariable', SyntaxAt(2, 1)
#
# Sass
#
Given vue (Sass region):
<style lang="sass">
$green: #42b983
</style>
Execute:
AssertEqual 'sassVariable', SyntaxAt(2, 1)
Given vue (Sass region with modifier):
<style lang="sass?indentedSyntax">
$green: #42b983
</style>
Execute:
AssertEqual 'sassVariable', SyntaxAt(2, 1)
#
# Stylus
#
Given vue (Sass region):
<style lang="stylus">
@import 'variables'
body
font: 12px Helvetica, Arial, sans-serif
</style>
Execute:
AssertEqual 'stylusImport', SyntaxAt(2, 1)
AssertEqual 'cssTagName', SyntaxAt(4, 1)
#
# TypeScript
#
Given vue (Typescript region using "ts" as name):
<script lang="ts">
@Component({})
</script>
Execute:
AssertEqual 'typescriptDecorators', SyntaxAt(2, 1)
Given vue (Typescript region using "typescript" as name):
<script lang="typescript">
@Component({})
</script>
Execute:
AssertEqual 'typescriptDecorators', SyntaxAt(2, 1)
Given vue (Typescript region using "ts" attribute):
<script ts>
@Component({})
</script>
Execute:
AssertEqual 'typescriptDecorators', SyntaxAt(2, 1)