summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Stankiewicz <sheerun@sher.pl>2021-04-14 12:11:13 +0200
committerAdam Stankiewicz <sheerun@sher.pl>2021-04-14 12:11:26 +0200
commit067e07e137d26ca6bc3f8496fe7bd569500d7fa4 (patch)
tree55e340bc5698fd426894568a0052db5ebe5e09b4
parent5de7022bcb4c7a155952dbeb666f912db3bde2af (diff)
downloadvim-polyglot-067e07e137d26ca6bc3f8496fe7bd569500d7fa4.tar.gz
vim-polyglot-067e07e137d26ca6bc3f8496fe7bd569500d7fa4.zip
Change svelte provider, fixes #700
-rw-r--r--README.md2
-rw-r--r--autoload/svelte.vim71
-rw-r--r--ftplugin/svelte.vim50
-rw-r--r--ftplugin/svelte/fold.vim131
-rw-r--r--indent/svelte.vim373
-rw-r--r--packages.yaml2
-rw-r--r--syntax/svelte-html.vim127
-rw-r--r--syntax/svelte.vim341
8 files changed, 850 insertions, 247 deletions
diff --git a/README.md b/README.md
index 86ac7b58..40674dd3 100644
--- a/README.md
+++ b/README.md
@@ -176,7 +176,7 @@ On top of all language packs from [vim repository](https://github.com/vim/vim/tr
- [smt2](https://github.com/bohlender/vim-smt2) (SMT syntax highlighting for smt2 and smt files)
- [solidity](https://github.com/TovarishFin/vim-solidity) (Solidity syntax highlighting for sol files)
- [stylus](https://github.com/wavded/vim-stylus) (Stylus syntax highlighting for styl and stylus files)
-- [svelte](https://github.com/evanleck/vim-svelte/tree/main) (Svelte syntax highlighting for svelte files)
+- [svelte](https://github.com/leafOfTree/vim-svelte-plugin) (Svelte syntax highlighting for svelte files)
- [svg-indent](https://github.com/jasonshell/vim-svg-indent)
- [svg](https://github.com/vim-scripts/svg.vim) (SVG syntax highlighting for svg files)
- [swift](https://github.com/keith/swift.vim) (Swift syntax highlighting for swift files)
diff --git a/autoload/svelte.vim b/autoload/svelte.vim
new file mode 100644
index 00000000..60d31469
--- /dev/null
+++ b/autoload/svelte.vim
@@ -0,0 +1,71 @@
+if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'autoload/svelte.vim')
+ finish
+endif
+
+let s:name = 'vim-svelte-plugin'
+let s:debug = exists("g:vim_svelte_plugin_debug")
+ \ && g:vim_svelte_plugin_debug == 1
+
+function! svelte#GetConfig(name, default)
+ let name = 'g:vim_svelte_plugin_'.a:name
+ return exists(name) ? eval(name) : a:default
+endfunction
+
+" Since svelte#Log and svelte#GetConfig are always called
+" in syntax and indent files,
+" this file will be sourced when opening the first svelte file
+if exists('##CursorMoved') && exists('*OnChangeSvelteSubtype')
+ augroup vim_svelte_plugin
+ autocmd!
+ autocmd CursorMoved,CursorMovedI,WinEnter *.svelte
+ \ call s:CheckSubtype()
+ augroup END
+
+ let s:subtype = ''
+ function! s:CheckSubtype()
+ let subtype = GetSvelteSubtype()
+
+ if s:subtype != subtype
+ call OnChangeSvelteSubtype(subtype)
+ let s:subtype = subtype
+ endif
+ endfunction
+endif
+
+function! s:SynsEOL(lnum)
+ let lnum = prevnonblank(a:lnum)
+ let cnum = strlen(getline(lnum))
+ return map(synstack(lnum, cnum), 'synIDattr(v:val, "name")')
+endfunction
+
+function! GetSvelteSubtype()
+ let lnum = line('.')
+ let cursyns = s:SynsEOL(lnum)
+ let syn = !empty(cursyns) ? get(cursyns, 0, '') : ''
+
+ let subtype = matchstr(syn, '\w\+\zeSvelte')
+ if subtype =~ 'css\w\+'
+ " For cssScss, cssLess, ...
+ let subtype = subtype[3:]
+ endif
+ let subtype = tolower(subtype)
+ return subtype
+endfunction
+
+function! GetSvelteTag(...)
+ let lnum = a:0 > 0 ? a:1 : line('.')
+ let cursyns = s:SynsEOL(lnum)
+ let syn = get(cursyns, 0, '')
+
+ if syn =~ 'SvelteTemplate'
+ let tag = 'template'
+ elseif syn =~ 'SvelteScript'
+ let tag = 'script'
+ elseif syn =~ 'SvelteStyle'
+ let tag = 'style'
+ else
+ let tag = ''
+ endif
+
+ return tag
+endfunction
diff --git a/ftplugin/svelte.vim b/ftplugin/svelte.vim
index cf32ef5b..051e085d 100644
--- a/ftplugin/svelte.vim
+++ b/ftplugin/svelte.vim
@@ -2,46 +2,24 @@ if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'ftplugin/svelte.vim
finish
endif
-" Vim filetype plugin
-" Language: Svelte 3 (HTML/JavaScript)
-" Author: Evan Lecklider <evan@lecklider.com>
-" Maintainer: Evan Lecklide <evan@lecklider.com>
-" URL: https://github.com/evanleck/vim-svelte
-if (exists('b:did_ftplugin'))
- finish
-endif
+if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
-" Matchit support
-if exists('loaded_matchit') && !exists('b:match_words')
- let b:match_ignorecase = 0
+if !has('nvim')
+ setlocal matchpairs+=<:>
+endif
- " In order:
- "
- " 1. Svelte control flow keywords.
- " 2. Parens.
- " 3-5. HTML tags pulled from Vim itself.
- "
- " https://github.com/vim/vim/blob/5259275347667a90fb88d8ea74331f88ad68edfc/runtime/ftplugin/html.vim#L29-L35
- let b:match_words =
- \ '#\%(if\|await\|each\)\>:\:\%(else\|catch\|then\)\>:\/\%(if\|await\|each\)\>,' .
- \ '{:},' .
+if exists("loaded_matchit")
+ let b:match_ignorecase = 1
+ let b:match_words = '<:>,' .
\ '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' .
\ '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' .
- \ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>'
+ \ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>,' .
+ \ '{#\(if\|each\)[^}]*}:{\:else[^}]*}:{\/\(if\|each\)},' .
+ \ '{#await[^}]*}:{\:then[^}]*}:{\/await},'
endif
-" ALE fixing and linting.
-if exists('g:loaded_ale')
- if !exists('b:ale_fixers')
- let b:ale_fixers = ['eslint', 'prettier', 'prettier_standard']
- endif
-
- if !exists('b:ale_linter_aliases')
- let b:ale_linter_aliases = ['css', 'javascript']
- endif
-
- if !exists('b:ale_linters')
- let b:ale_linters = ['stylelint', 'eslint']
- endif
-endif
+" Indent correctly with template string for vim-javascript/builtin
+" indentexpr
+let b:syng_str = '^\%(.*template\)\@!.*string\|special'
+let b:syng_strcom = '^\%(.*template\)\@!.*string\|comment\|regex\|special\|doc'
diff --git a/ftplugin/svelte/fold.vim b/ftplugin/svelte/fold.vim
new file mode 100644
index 00000000..2732660a
--- /dev/null
+++ b/ftplugin/svelte/fold.vim
@@ -0,0 +1,131 @@
+if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'ftplugin/svelte/fold.vim')
+ finish
+endif
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Config {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+let s:use_foldexpr = exists("g:vim_svelte_plugin_use_foldexpr")
+ \ && g:vim_svelte_plugin_use_foldexpr == 1
+"}}}
+
+if !s:use_foldexpr | finish | endif
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Settings {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+setlocal foldmethod=expr
+setlocal foldexpr=GetSvelteFold(v:lnum)
+"}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Variables {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+let s:empty_line = '\v^\s*$'
+let s:block_end = '\v^\s*}|]|\)'
+let s:svelte_tag_start = '\v^\<\w+'
+let s:svelte_tag_end = '\v^\<\/\w+'
+let s:svelte_internal_blocks = '\v:(else|then|catch)'
+"}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Functions {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" see :h fold-expr
+" value meaning
+" 0 the line is not in a fold
+" 1, 2, .. the line is in a fold with this level
+" -1 the fold level is undefined, use the fold level of a
+" line before or after this line, whichever is the
+" lowest.
+" "=" use fold level from the previous line
+" "a1", "a2", .. add one, two, .. to the fold level of the previous
+" line, use the result for the current line
+" "s1", "s2", .. subtract one, two, .. from the fold level of the
+" previous line, use the result for the next line
+" ">1", ">2", .. a fold with this level starts at this line
+" "<1", "<2", .. a fold with this level ends at this line
+function! GetSvelteFold(lnum)
+ let this_line = getline(a:lnum)
+ let next_line = getline(a:lnum + 1)
+
+ " Handle empty lines
+ if this_line =~ s:empty_line
+ return -1
+ endif
+
+ " Handle start/end tags
+ if this_line =~ s:svelte_tag_start
+ return '>1'
+ endif
+ if this_line =~ s:svelte_tag_end
+ " If return '<1', fold will get incorrect with prev line
+ return 1
+ endif
+
+ " Fold by indent
+ if a:lnum > 1
+ let prev_indent = s:IndentLevel(a:lnum - 1)
+ else
+ let prev_indent = 0
+ endif
+ let this_indent = s:IndentLevel(a:lnum)
+ let next_indent = s:IndentLevel(s:NextNonBlankLine(a:lnum))
+
+ " Fold separately on blocks
+ if this_line =~ s:svelte_internal_blocks
+ return '>'.next_indent
+ endif
+
+ if GetSvelteTag(a:lnum) == 'script'
+ " Handle closing '}'
+ if this_line =~ '\v^\s*},?\s*$'
+ return '<'.prev_indent
+ endif
+
+ " --this
+ " ----next
+ if this_indent < next_indent
+ return '>'.next_indent
+ endif
+
+ " ----this
+ " --next
+ if this_indent >= next_indent
+ return this_indent
+ endif
+ else
+ " Template or style
+ return this_indent
+ endif
+endfunction
+
+function! s:IndentLevel(lnum)
+ " Add 1 to indentLevel, so start/end tags can fold properly
+ return indent(a:lnum) / &shiftwidth + 1
+endfunction
+
+function! s:NextNonBlankLine(lnum)
+ let next_line = a:lnum + 1
+ let last_line = line('$')
+
+ while next_line <= last_line
+ if getline(next_line) =~ '\v\S'
+ return next_line
+ endif
+
+ let next_line += 1
+ endwhile
+
+ return 0
+endfunction
+"}}}
+" vim: fdm=marker
diff --git a/indent/svelte.vim b/indent/svelte.vim
index cb01c424..047d1479 100644
--- a/indent/svelte.vim
+++ b/indent/svelte.vim
@@ -2,160 +2,301 @@ if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'indent/svelte.vim')
finish
endif
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Vim indent file
-" Language: Svelte 3 (HTML/JavaScript)
-" Author: Evan Lecklider <evan@lecklider.com>
-" Maintainer: Evan Lecklide <evan@lecklider.com>
-" URL: https://github.com/evanleck/vim-svelte
-
+"
+" Language: Svelte
+" Maintainer: leafOfTree <leafvocation@gmail.com>
+"
+" CREDITS: Inspired by mxw/vim-jsx.
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if exists("b:did_indent")
finish
endif
-if !exists('g:svelte_indent_script')
- let g:svelte_indent_script = 1
-endif
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Variables {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+let s:name = 'vim-svelte-plugin'
+" Let <template> handled by HTML
+let s:svelte_tag_start = '\v^\<(script|style)'
+let s:svelte_tag_end = '\v^\<\/(script|style)'
+let s:template_tag = '\v^\s*\<\/?template'
+" https://developer.mozilla.org/en-US/docs/Glossary/Empty_element
+let s:empty_tagname = '(area|base|br|col|embed|hr|input|img|keygen|link|meta|param|source|track|wbr)'
+let s:empty_tag = '\v\C\<'.s:empty_tagname.'[^/]*\>'
+let s:empty_tag_start = '\v\<'.s:empty_tagname.'[^\>]*$'
+let s:empty_tag_end = '\v^\s*[^\<\>\/]*\>\s*'
+let s:tag_end = '\v^\s*\/?\>\s*'
+let s:oneline_block = '^\s*{#.*{/.*}\s*$'
+"}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Config {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+let s:use_pug = svelte#GetConfig('use_pug', 0)
+let s:use_sass = svelte#GetConfig('use_sass', 0)
+let s:use_coffee = svelte#GetConfig('use_coffee', 0)
+let s:use_typescript = svelte#GetConfig('use_typescript', 0)
+let s:has_init_indent = svelte#GetConfig('has_init_indent', 1)
+let s:debug = svelte#GetConfig('debug', 0)
+"}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Load indent method {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Save shiftwidth
+let s:sw = &sw
+
+" Use lib/indent/ files for compatibility
+unlet! b:did_indent
+runtime lib/indent/xml.vim
-if !exists('g:svelte_indent_style')
- let g:svelte_indent_style = 1
-endif
+unlet! b:did_indent
+runtime lib/indent/css.vim
-" Try to mirror Svelte's indent settings so the HTML indenting scripts match.
-if g:svelte_indent_script
- let b:html_indent_script1 = "inc"
-else
- let b:html_indent_script1 = "zero"
+" Use normal indent files
+unlet! b:did_indent
+runtime! indent/javascript.vim
+let b:javascript_indentexpr = &indentexpr
+
+if s:use_pug
+ unlet! b:did_indent
+ let s:save_formatoptions = &formatoptions
+ runtime! indent/pug.vim
+ let &formatoptions = s:save_formatoptions
endif
-if g:svelte_indent_style
- let b:html_indent_style1 = "inc"
-else
- let b:html_indent_style1 = "zero"
+if s:use_sass
+ unlet! b:did_indent
+ runtime! indent/sass.vim
endif
-runtime! indent/html.vim
-unlet! b:did_indent
+if s:use_coffee
+ unlet! b:did_indent
+ runtime! indent/coffee.vim
+endif
-let s:html_indent = &l:indentexpr
-let b:did_indent = 1
+if s:use_typescript
+ unlet! b:did_indent
+ runtime! indent/typescript.vim
+endif
+" Recover shiftwidth
+let &sw = s:sw
+"}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Settings {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" JavaScript indentkeys
+setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e,:,=:else
+" XML indentkeys
+setlocal indentkeys+=*<Return>,<>>,<<>,/
setlocal indentexpr=GetSvelteIndent()
-setlocal indentkeys=o,O,*<Return>,<>>,{,},0),0],!^F,;,=:else,=:then,=:catch,=/if,=/each,=/await
-
-" Only define the function once.
-if exists('*GetSvelteIndent')
- finish
-endif
+"}}}
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Functions {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! GetSvelteIndent()
- let current_line_number = v:lnum
-
- if current_line_number == 0
- return 0
- endif
-
- let current_line = getline(current_line_number)
+ let prevlnum = prevnonblank(v:lnum-1)
+ let prevline = getline(prevlnum)
+ let prevsyns = s:SynsSOL(prevlnum)
+
+ let curline = getline(v:lnum)
+ let cursyns = s:SynsSOL(v:lnum)
+ let cursyn = get(cursyns, 0, '')
+
+ if s:SynHTML(cursyn)
+ call s:Log('syntax: html')
+ let ind = XmlIndentGet(v:lnum, 0)
+ if prevline =~? s:empty_tag
+ call s:Log('previous line is empty tag')
+ let ind = ind - &sw
+ endif
- " Opening script and style tags should be all the way outdented.
- if current_line =~ '^\s*</\?\(script\|style\)'
- return 0
- endif
+ if s:IsBlockStart(prevsyns) && prevline !~ s:oneline_block
+ call s:Log('increase block indent')
+ let ind = ind + &sw
+ endif
- let previous_line_number = prevnonblank(current_line_number - 1)
- let previous_line = getline(previous_line_number)
- let previous_line_indent = indent(previous_line_number)
+ if s:IsBlockEnd(cursyns, curline)
+ call s:Log('decrease block indent')
+ let ind = ind - &sw
+ endif
- " The inside of scripts an styles should be indented unless disabled.
- if previous_line =~ '^\s*<script'
- if g:svelte_indent_script
- return previous_line_indent + shiftwidth()
+ " Align '/>' and '>' with '<' for multiline tags.
+ if curline =~? s:tag_end
+ let ind = ind - &sw
+ endif
+ " Then correct the indentation of any element following '/>' or '>'.
+ if prevline =~? s:tag_end
+ let ind = ind + &sw
+
+ "Decrease indent if prevlines are a multiline empty tag
+ let [start, end] = s:PrevMultilineEmptyTag(v:lnum)
+ if end == prevlnum
+ call s:Log('previous line is a multiline empty tag')
+ let ind = indent(v:lnum - 1)
+ endif
+ endif
+ elseif s:SynPug(cursyn)
+ call s:Log('syntax: pug')
+ let ind = GetPugIndent()
+ elseif s:SynCoffee(cursyn)
+ call s:Log('syntax: coffee')
+ let ind = GetCoffeeIndent(v:lnum)
+ elseif s:SynTypeScript(cursyn)
+ call s:Log('syntax: typescript')
+ let ind = GetTypescriptIndent()
+ elseif s:SynSASS(cursyn)
+ call s:Log('syntax: sass')
+ let ind = GetSassIndent()
+ elseif s:SynStyle(cursyn)
+ call s:Log('syntax: style')
+ let ind = GetCSSIndent()
+ else
+ call s:Log('syntax: javascript')
+ if len(b:javascript_indentexpr)
+ let ind = eval(b:javascript_indentexpr)
else
- return previous_line_indent
+ let ind = cindent(v:lnum)
endif
endif
- if previous_line =~ '^\s*<style'
- if g:svelte_indent_style
- return previous_line_indent + shiftwidth()
- else
- return previous_line_indent
+ if curline =~? s:svelte_tag_start || curline =~? s:svelte_tag_end
+ \|| prevline =~? s:svelte_tag_end
+ \|| (curline =~ s:template_tag && s:SynPug(cursyn))
+ call s:Log('current line is svelte tag or previous line is svelte tag end')
+ call s:Log('... or current line is pug template tag')
+ let ind = 0
+ elseif s:has_init_indent
+ if s:SynSvelteScriptOrStyle(cursyn) && ind < 1
+ call s:Log('add initial indent')
+ let ind = &sw
endif
+ elseif prevline =~? s:svelte_tag_start
+ call s:Log('previous line is svelte tag start')
+ let ind = 0
endif
- execute "let indent = " . s:html_indent
+ call s:Log('indent: '.ind)
+ return ind
+endfunction
- " For some reason, the HTML CSS indentation keeps indenting the next line over
- " and over after each style declaration.
- if searchpair('<style>', '', '</style>', 'bW') && previous_line =~ ';$' && current_line !~ '}'
- return previous_line_indent
- endif
+function! s:IsBlockStart(prevsyns)
+ let prevsyn_second = get(a:prevsyns, 1, '')
+ " Some HTML tags add an extra syntax layer
+ let prevsyn_third = get(a:prevsyns, 2, '')
+ return s:SynBlockBody(prevsyn_second)
+ \ || s:SynBlockStart(prevsyn_second)
+ \ || s:SynBlockBody(prevsyn_third)
+ \ || s:SynBlockStart(prevsyn_third)
+endfunction
- " "/await" or ":catch" or ":then"
- if current_line =~ '^\s*{\s*\/await' || current_line =~ '^\s*{\s*:\(catch\|then\)'
- let await_start = searchpair('{\s*#await\>', '', '{\s*\/await\>', 'bW')
+function! s:IsBlockEnd(cursyns, curline)
+ let cursyn_second = get(a:cursyns, 1, '')
+ " Some HTML tags add an extra syntax layer
+ let cursyn_third = get(a:cursyns, 2, '')
+ return a:curline !~ '^\s*$'
+ \ && (s:SynBlockBody(cursyn_second)
+ \ || s:SynBlockEnd(cursyn_second)
+ \ || s:SynBlockBody(cursyn_third)
+ \ || s:SynBlockEnd(cursyn_third))
+endfunction
- if await_start
- return indent(await_start)
- endif
- endif
+function! s:SynsEOL(lnum)
+ let lnum = prevnonblank(a:lnum)
+ let col = strlen(getline(lnum))
+ return map(synstack(lnum, col), 'synIDattr(v:val, "name")')
+endfunction
- " "/each"
- if current_line =~ '^\s*{\s*\/each'
- let each_start = searchpair('{\s*#each\>', '', '{\s*\/each\>', 'bW')
+function! s:SynsSOL(lnum)
+ let lnum = prevnonblank(a:lnum)
+ let col = match(getline(lnum), '\S') + 1
+ return map(synstack(lnum, col), 'synIDattr(v:val, "name")')
+endfunction
- if each_start
- return indent(each_start)
- endif
- endif
+function! s:SynHTML(syn)
+ return a:syn ==? 'htmlSvelteTemplate'
+endfunction
- " "/if"
- if current_line =~ '^\s*{\s*\/if'
- let if_start = searchpair('{\s*#if\>', '', '{\s*\/if\>', 'bW')
+function! s:SynBlockBody(syn)
+ return a:syn ==? 'svelteBlockBody'
+endfunction
- if if_start
- return indent(if_start)
- endif
- endif
+function! s:SynBlockStart(syn)
+ return a:syn ==? 'svelteBlockStart'
+endfunction
- " ":else" is tricky because it can match an opening "#each" _or_ an opening
- " "#if", so we try to be smart and look for the closest of the two.
- if current_line =~ '^\s*{\s*:else'
- let if_start = searchpair('{\s*#if\>', '', '{\s*\/if\>', 'bW')
+function! s:SynBlockEnd(syn)
+ return a:syn ==? 'svelteBlockEnd'
+endfunction
- " If it's an "else if" then we know to look for an "#if"
- if current_line =~ '^\s*{\s*:else if' && if_start
- return indent(if_start)
- else
- " The greater line number will be closer to the cursor position because
- " we're searching backward.
- return indent(max([if_start, searchpair('{\s*#each\>', '', '{\s*\/each\>', 'bW')]))
- endif
- endif
+function! s:SynPug(syn)
+ return a:syn ==? 'pugSvelteTemplate'
+endfunction
- " "#if" or "#each"
- if previous_line =~ '^\s*{\s*#\(if\|each\|await\)'
- return previous_line_indent + shiftwidth()
- endif
+function! s:SynCoffee(syn)
+ return a:syn ==? 'coffeeSvelteScript'
+endfunction
- " ":else" or ":then"
- if previous_line =~ '^\s*{\s*:\(else\|catch\|then\)'
- return previous_line_indent + shiftwidth()
- endif
+function! s:SynTypeScript(syn)
+ return a:syn ==? 'typescriptSvelteScript'
+endfunction
+
+function! s:SynSASS(syn)
+ return a:syn ==? 'cssSassSvelteStyle'
+endfunction
+
+function! s:SynStyle(syn)
+ return a:syn =~? 'SvelteStyle'
+endfunction
+
+function! s:SynSvelteScriptOrStyle(syn)
+ return a:syn =~? '\v(SvelteStyle)|(SvelteScript)'
+endfunction
- " Custom element juggling for abnormal self-closing tags (<Widget />),
- " capitalized component tags (<Widget></Widget>), and custom svelte tags
- " (<svelte:head></svelte:head>).
- if synID(previous_line_number, match(previous_line, '\S') + 1, 0) == hlID('htmlTag')
- \ && synID(current_line_number, match(current_line, '\S') + 1, 0) != hlID('htmlEndTag')
- let indents_match = indent == previous_line_indent
- let previous_closes = previous_line =~ '/>$'
-
- if indents_match && !previous_closes && previous_line =~ '<\(\u\|\l\+:\l\+\)'
- return previous_line_indent + shiftwidth()
- elseif !indents_match && previous_closes
- return previous_line_indent
+function! s:PrevMultilineEmptyTag(lnum)
+ let lnum = a:lnum - 1
+ let lnums = [0, 0]
+ while lnum > 0
+ let line = getline(lnum)
+ if line =~? s:empty_tag_end
+ let lnums[1] = lnum
endif
- endif
- return indent
+ if line =~? s:tag_start
+ if line =~? s:empty_tag_start
+ let lnums[0] = lnum
+ return lnums
+ else
+ return [0, 0]
+ endif
+ endif
+
+ let lnum = lnum - 1
+ endwhile
endfunction
+
+function! s:Log(msg)
+ if s:debug
+ echom '['.s:name.']['.v:lnum.'] '.a:msg
+ endif
+endfunction
+"}}}
+
+let b:did_indent = 1
+" vim: fdm=marker
diff --git a/packages.yaml b/packages.yaml
index d244ef49..62fda539 100644
--- a/packages.yaml
+++ b/packages.yaml
@@ -1574,7 +1574,7 @@ filetypes:
- stylus
---
name: svelte
-remote: evanleck/vim-svelte@main
+remote: leafOfTree/vim-svelte-plugin
filetypes:
- name: svelte
linguist: Svelte
diff --git a/syntax/svelte-html.vim b/syntax/svelte-html.vim
new file mode 100644
index 00000000..c0b243b1
--- /dev/null
+++ b/syntax/svelte-html.vim
@@ -0,0 +1,127 @@
+if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'syntax/svelte-html.vim')
+ finish
+endif
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Config {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+let s:highlight_svelte_attr = svelte#GetConfig('highlight_svelte_attr', 0)
+")}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Syntax highlight {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+syntax match svelteComponentName containedin=htmlTagN '\v\C<[a-zA-Z0-9]+(\.[A-Z][a-zA-Z0-9]+)*>'
+
+syntax match svelteComponentName containedin=htmlTagN '\v\C<[a-z0-9]+(-[a-z0-9]+)+>'
+
+syntax match svelteComponentName containedin=htmlTagN '\vsvelte:\w*'
+
+" Syntax for vim-svelte-theme
+syntax match htmlAttr '\v(\S|\<)@<![^\/\<\>[:blank:]]+' containedin=htmlTag
+ \ contains=htmlString,svelteValue,htmlArg
+syntax match htmlAttrEqual '\v\=' containedin=htmlAttr
+
+syntax match svelteAttr
+ \ '\v(\S)@<!(on|bind|use|in|out|transition|animate|class):[^\=\>[:blank:]]+(\=\"[^"]*\"|\=\{[^}]*\})?'
+ \ containedin=htmlTag
+ \ contains=svelteKey,svelteValue
+
+syntax match svelteKey contained '\v(on|bind|use|in|out|transition|animate|class):[^\=\>[:blank:]]+'
+syntax match svelteValue contained '\v\{[^}]*\}'
+
+syntax region svelteExpression
+ \ containedin=htmlH.*,htmlItalic
+ \ matchgroup=svelteBrace
+ \ transparent
+ \ start="{"
+ \ end="}\(}\)\@!"
+
+syntax region svelteExpression
+ \ containedin=htmlSvelteTemplate,svelteValue,htmlString,htmlValue,htmlArg,htmlTag
+ \ contains=@simpleJavascriptExpression,svelteAtTags
+ \ matchgroup=svelteBrace
+ \ transparent
+ \ start="{"
+ \ end="}\(}\)\@!"
+
+syntax region svelteExpression
+ \ containedin=htmlTag
+ \ contains=@simpleJavascriptExpression,svelteAtTags,svelteShortProp
+ \ matchgroup=svelteBrace
+ \ transparent
+ \ start="{"
+ \ end="}\(}\)\@!"
+
+syntax match svelteAtTags '\v\@(html|debug)'
+syntax match svelteShortProp '\v<\w+>'
+
+syntax region svelteBlockBody
+ \ containedin=htmlSvelteTemplate,htmlLink
+ \ contains=@simpleJavascriptExpression,svelteBlockKeyword
+ \ matchgroup=svelteBrace
+ \ start="{:"
+ \ end="}"
+
+syntax region svelteBlockStart
+ \ containedin=htmlSvelteTemplate,htmlLink
+ \ contains=@simpleJavascriptExpression,svelteBlockKeyword
+ \ matchgroup=svelteBrace
+ \ start="{#"
+ \ end="}"
+
+syntax region svelteBlockEnd
+ \ containedin=htmlSvelteTemplate,htmlLink
+ \ contains=@simpleJavascriptExpression,svelteBlockKeyword
+ \ matchgroup=svelteBrace
+ \ start="{\/"
+ \ end="}"
+
+syntax keyword svelteBlockKeyword if else each await then catch as
+
+syntax cluster simpleJavascriptExpression
+ \ contains=javaScriptStringS,javaScriptStringD,javaScriptTemplateString,javascriptNumber,javaScriptOperator
+
+" Redefine JavaScript syntax
+syntax region javaScriptStringS
+ \ start=+'+ skip=+\\\\\|\\'+ end=+'\|$+ contained
+syntax region javaScriptStringD
+ \ start=+"+ skip=+\\\\\|\\"+ end=+"\|$+ contained
+syntax region javaScriptTemplateString
+ \ start=+`+ skip=+\\`+ end=+`+ contained
+ \ contains=javaScriptTemplateExpression
+syntax region javaScriptTemplateExpression
+ \ matchgroup=Type
+ \ start=+${+ end=+}+ keepend contained
+
+syntax match javaScriptNumber '\v<-?\d+L?>|0[xX][0-9a-fA-F]+>' contained
+syntax match javaScriptOperator '[-!|&+<>=%*~^]' contained
+syntax match javaScriptOperator '\v(*)@<!/(/|*)@!' contained
+syntax keyword javaScriptOperator delete instanceof typeof void new in of contained
+
+highlight default link svelteAttr htmlTag
+if s:highlight_svelte_attr
+ highlight default link svelteKey Type
+ highlight default link svelteValue None
+else
+ highlight default link svelteKey htmlArg
+ highlight default link svelteValue String
+endif
+
+highlight default link svelteBrace Type
+highlight default link svelteBlockKeyword Statement
+highlight default link svelteComponentName htmlTagName
+highlight default link javaScriptTemplateString String
+highlight default link javaScriptStringS String
+highlight default link javaScriptStringD String
+highlight default link javaScriptNumber Constant
+highlight default link javaScriptOperator Operator
+highlight default link svelteAttr htmlTag
+highlight default link svelteAttrEqual htmlTag
+highlight default link svelteShortProp htmlValue
+"}}}
+" vim: fdm=marker
diff --git a/syntax/svelte.vim b/syntax/svelte.vim
index d872826c..f67c8caf 100644
--- a/syntax/svelte.vim
+++ b/syntax/svelte.vim
@@ -2,123 +2,278 @@ if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'syntax/svelte.vim')
finish
endif
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Vim syntax file
-" Language: Svelte 3 (HTML/JavaScript)
-" Author: Evan Lecklider <evan@lecklider.com>
-" Maintainer: Evan Lecklide <evan@lecklider.com>
-" Depends: pangloss/vim-javascript
-" URL: https://github.com/evanleck/vim-svelte
"
-" Like vim-jsx, this depends on the pangloss/vim-javascript syntax package (and
-" is tested against it exclusively). If you're using vim-polyglot, then you're
-" all set.
-
-if exists("b:current_syntax")
+" Language: Svelte
+" Maintainer: leaf <leafvocation@gmail.com>
+"
+" CREDITS: Inspired by mxw/vim-jsx.
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+if exists("b:current_syntax") && b:current_syntax == 'svelte'
finish
endif
-" Read HTML to begin with.
-runtime! syntax/html.vim
-unlet! b:current_syntax
+" For advanced users, this variable can be used to avoid overload
+let b:current_loading_main_syntax = 'svelte'
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Config {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+let s:load_full_syntax = svelte#GetConfig('load_full_syntax', 0)
+let s:use_pug = svelte#GetConfig('use_pug', 0)
+let s:use_less = svelte#GetConfig('use_less', 0)
+let s:use_sass = svelte#GetConfig('use_sass', 0)
+let s:use_coffee = svelte#GetConfig('use_coffee', 0)
+let s:use_typescript = svelte#GetConfig('use_typescript', 0)
+"}}}
-" Expand HTML tag names to include mixed case, periods, and colons.
-syntax match htmlTagName contained "\<[a-zA-Z:\.]*\>"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Functions {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:LoadSyntax(group, type)
+ if s:load_full_syntax
+ call s:LoadFullSyntax(a:group, a:type)
+ else
+ call s:LoadDefaultSyntax(a:group, a:type)
+ endif
+endfunction
-" Special attributes that include some kind of binding e.g. "on:click",
-" "bind:something", etc.
-syntax match svelteKeyword "\<[a-z]\+:[a-zA-Z|]\+=" contained containedin=htmlTag
+function! s:LoadDefaultSyntax(group, type)
+ unlet! b:current_syntax
+ let syntaxPaths = ['$VIMRUNTIME', '$VIM/vimfiles', '$HOME/.vim']
+ for path in syntaxPaths
+ let file = expand(path).'/syntax/'.a:type.'.vim'
+ if filereadable(file)
+ execute 'syntax include '.a:group.' '.file
+ endif
+ endfor
+endfunction
-" The "slot" attribute has special meaning.
-syntax keyword svelteKeyword slot contained containedin=htmlTag
+function! s:LoadFullSyntax(group, type)
+ call s:SetCurrentSyntax(a:type)
+ exec 'syntax include '.a:group.' syntax/'.a:type.'.vim'
+endfunction
-" According to vim-jsx, you can let jsBlock take care of ending the region.
-" https://github.com/mxw/vim-jsx/blob/master/after/syntax/jsx.vim
-syntax region svelteExpression start="{" end="" contains=jsBlock,javascriptBlock containedin=htmlString,htmlTag,htmlArg,htmlValue,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,htmlHead,htmlTitle,htmlBoldItalicUnderline,htmlUnderlineBold,htmlUnderlineItalicBold,htmlUnderlineBoldItalic,htmlItalicUnderline,htmlItalicBold,htmlItalicBoldUnderline,htmlItalicUnderlineBold,htmlLink,htmlLeadingSpace,htmlBold,htmlBoldUnderline,htmlBoldItalic,htmlBoldUnderlineItalic,htmlUnderline,htmlUnderlineItalic,htmlItalic,htmlStrike,javaScript
+" Settings to avoid syntax overload
+function! s:SetCurrentSyntax(type)
+ if a:type == 'coffee'
+ syntax cluster coffeeJS contains=@htmlJavaScript
-" Block conditionals.
-syntax match svelteConditional "#if" contained containedin=jsBlock,javascriptBlock
-syntax match svelteConditional "/if" contained containedin=jsBlock,javascriptBlock
-syntax match svelteConditional ":else if" contained containedin=jsBlock,javascriptBlock
-syntax match svelteConditional ":else" contained containedin=jsBlock,javascriptBlock
+ " Avoid overload of `javascript.vim`
+ let b:current_syntax = 'svelte'
+ else
+ unlet! b:current_syntax
+ endif
+endfunction
+"}}}
-" Block keywords.
-syntax match svelteKeyword "#await" contained containedin=jsBlock,javascriptBlock
-syntax match svelteKeyword "/await" contained containedin=jsBlock,javascriptBlock
-syntax match svelteKeyword ":catch" contained containedin=jsBlock,javascriptBlock
-syntax match svelteKeyword ":then" contained containedin=jsBlock,javascriptBlock
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Load main syntax {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Load syntax/html.vim to syntax group, which loads full JavaScript and CSS
+" syntax. It defines group htmlJavaScript and htmlCss.
+call s:LoadSyntax('@HTMLSyntax', 'html')
-" Inline keywords.
-syntax match svelteKeyword "@html" contained containedin=jsBlock,javascriptBlock
-syntax match svelteKeyword "@debug" contained containedin=jsBlock,javascriptBlock
+" Load svelte-html syntax
+syntax include syntax/svelte-html.vim
-" Repeat functions.
-syntax match svelteRepeat "#each" contained containedin=jsBlock,javascriptBlock
-syntax match svelteRepeat "/each" contained containedin=jsBlock,javascriptBlock
+" Avoid overload
+if !hlexists('cssTagName')
+ call s:LoadSyntax('@htmlCss', 'css')
+endif
-highlight def link svelteConditional Conditional
-highlight def link svelteKeyword Keyword
-highlight def link svelteRepeat Repeat
+" Avoid overload
+if !hlexists('javaScriptComment')
+ call s:LoadSyntax('@htmlJavaScript', 'javascript')
+endif
+"}}}
-" Preprocessed languages that aren't supported out of the box by Svelte require
-" additional syntax files to be pulled in and can slow Vim down a bit. For that
-" reason, preprocessed languages must be enabled manually. Note that some may
-" require additional plugins that contain the actual syntax definitions.
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"
-" Heavily cribbed from https://github.com/posva/vim-vue and largely completed by
-" @davidroeca (thank you!).
-
-" A syntax should be registered if there's a valid syntax definition known to
-" Vim and it is enabled for the Svelte plugin.
-function! s:enabled(language)
- " Check whether a syntax file for {language} exists
- let s:syntax_name = get(a:language, 'as', a:language.name)
- if empty(globpath(&runtimepath, 'syntax/' . s:syntax_name . '.vim'))
- return 0
- endif
+" Load pre-processors syntax {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" If pug is enabled, load vim-pug syntax
+if s:use_pug
+ call s:LoadFullSyntax('@PugSyntax', 'pug')
+endif
+
+" If less is enabled, load less syntax
+if s:use_less
+ call s:LoadSyntax('@LessSyntax', 'less')
+ runtime! after/syntax/less.vim
+endif
- " If g:svelte_preprocessors is set, check for it there, otherwise return 0.
- if exists('g:svelte_preprocessors') && type(g:svelte_preprocessors) == v:t_list
- return index(g:svelte_preprocessors, a:language.name) != -1
+" If sass is enabled, load sass syntax
+if s:use_sass
+ call s:LoadSyntax('@SassSyntax', 'sass')
+ runtime! after/syntax/sass.vim
+endif
+
+" If CoffeeScript is enabled, load the syntax. Keep name consistent with
+" vim-coffee-script/after/html.vim
+if s:use_coffee
+ call s:LoadFullSyntax('@htmlCoffeeScript', 'coffee')
+endif
+
+" If TypeScript is enabled, load the syntax.
+if s:use_typescript
+ call s:LoadFullSyntax('@TypeScript', 'typescript')
+endif
+"}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Syntax highlight {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" All start with html/javascript/css for emmet-vim in-file type detection
+" Normal tag template
+syntax region htmlSvelteTemplate fold
+ \ start=+<[-:a-zA-Z0-9]\+[^>]*>$+
+ \ end=+^</[-:a-zA-Z0-9]\+>+
+ \ keepend contains=@HTMLSyntax
+" Start tag across multiple lines or Empty tag across multiple lines
+syntax region htmlSvelteTemplate fold
+ \ start=+<[-:a-zA-Z0-9]\+[^>]*$+
+ \ end=+^\(<\/[-:a-zA-Z0-9]\+>\)\|^\([^<]*\/>\)+
+ \ keepend contains=@HTMLSyntax
+" Tag in one line
+syntax match htmlSvelteTemplate fold
+ \ +<[-:a-zA-Z0-9]\+[^>]*>.*</[-:a-zA-Z0-9]\+>+
+ \ contains=@HTMLSyntax
+" Empty tag in one line
+syntax match htmlSvelteTemplate fold
+ \ +<[-:a-zA-Z0-9]\+[^>]*/>+
+ \ contains=@HTMLSyntax
+" @html,@debug tag in one line
+syntax match htmlSvelteTemplate fold
+ \ +{@\(html\|debug\)[^}]*}+
+ \ contains=@HTMLSyntax
+" Control blocks like {#if ...}, {#each ...}
+syntax region htmlSvelteTemplate fold
+ \ start=+{#[-a-zA-Z0-9]\+[^}]*}+
+ \ end=+^{/[-a-zA-Z0-9]\+}+
+ \ keepend contains=@HTMLSyntax
+
+syntax region javascriptSvelteScript fold
+ \ start=+<script[^>]*>+
+ \ end=+</script>+
+ \ keepend
+ \ contains=@htmlJavaScript,jsImport,jsExport,svelteTag,svelteKeyword
+
+syntax region cssSvelteStyle fold
+ \ start=+<style[^>]*>+
+ \ end=+</style>+
+ \ keepend contains=@htmlCss,svelteTag
+
+" Preprocessors syntax
+syntax region pugSvelteTemplate fold
+ \ start=+<template[^>]*lang="pug"[^>]*>+
+ \ end=+</template>+
+ \ keepend contains=@PugSyntax,svelteTag
+
+syntax region coffeeSvelteScript fold
+ \ start=+<script[^>]*lang="coffee"[^>]*>+
+ \ end=+</script>+
+ \ keepend contains=@htmlCoffeeScript,jsImport,jsExport,svelteTag
+
+syntax region typescriptSvelteScript fold
+ \ start=+<script[^>]*lang="\(ts\|typescript\)"[^>]*>+
+ \ end=+</script>+
+ \ keepend contains=@TypeScript,svelteTag
+
+syntax region cssLessSvelteStyle fold
+ \ start=+<style[^>]*lang="less"[^>]*>+
+ \ end=+</style>+
+ \ keepend contains=@LessSyntax,svelteTag
+syntax region cssSassSvelteStyle fold
+ \ start=+<style[^>]*lang="sass"[^>]*>+
+ \ end=+</style>+
+ \ keepend contains=@SassSyntax,svelteTag
+syntax region cssScssSvelteStyle fold
+ \ start=+<style[^>]*lang="scss"[^>]*>+
+ \ end=+</style>+
+ \ keepend contains=@SassSyntax,svelteTag
+
+syntax region svelteTag
+ \ start=+^<[^/]+ end=+>+ skip=+></+
+ \ contained contains=htmlTagN,htmlString,htmlArg fold
+syntax region svelteTag
+ \ start=+^</+ end=+>+
+ \ contained contains=htmlTagN,htmlString,htmlArg
+syntax keyword svelteKeyword $ contained
+
+highlight default link svelteTag htmlTag
+highlight default link svelteKeyword Keyword
+highlight default link cssUnitDecorators2 Number
+highlight default link cssKeyFrameProp2 Constant
+"}}}
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+"
+" Syntax patch {{{
+"
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Patch 7.4.1142
+if has("patch-7.4-1142")
+ if has("win32")
+ syn iskeyword @,48-57,_,128-167,224-235,$
else
- return 0
+ syn iskeyword @,48-57,_,192-255,$
endif
-endfunction
+endif
-" Default tag definitions.
-let s:languages = [
- \ { 'name': 'less', 'tag': 'style' },
- \ { 'name': 'scss', 'tag': 'style' },
- \ { 'name': 'sass', 'tag': 'style' },
- \ { 'name': 'stylus', 'tag': 'style' },
- \ { 'name': 'typescript', 'tag': 'script' },
- \ ]
-
-" Add global tag definitions to our defaults.
-if exists('g:svelte_preprocessor_tags') && type(g:svelte_preprocessor_tags) == v:t_list
- let s:languages += g:svelte_preprocessor_tags
+" Style
+" Redefine (less|sass)Definition to highlight <style> correctly and
+" enable emmet-vim css type.
+if s:use_less
+ silent! syntax clear lessDefinition
+ syntax region cssLessDefinition matchgroup=cssBraces
+ \ contains=@LessSyntax,cssLessDefinition
+ \ contained containedin=cssLessSvelteStyle
+ \ start="{" end="}"
+endif
+if s:use_sass
+ silent! syntax clear sassDefinition
+ syntax region cssSassDefinition matchgroup=cssBraces
+ \ contains=@SassSyntax,cssSassDefinition
+ \ contained containedin=cssScssSvelteStyle,cssSassSvelteStyle
+ \ start="{" end="}"
endif
-for s:language in s:languages
- let s:attr = '\(lang\|type\)=\("\|''\)[^\2]*' . s:language.name . '[^\2]*\2'
- let s:start = '<' . s:language.tag . '\>\_[^>]*' . s:attr . '\_[^>]*>'
+" Avoid css syntax interference
+silent! syntax clear cssUnitDecorators
+" Have to use a different name
+syntax match cssUnitDecorators2
+ \ /\(#\|-\|+\|%\|mm\|cm\|in\|pt\|pc\|em\|ex\|px\|ch\|rem\|vh\|vw\|vmin\|vmax\|dpi\|dppx\|dpcm\|Hz\|kHz\|s\|ms\|deg\|grad\|rad\)\ze\(;\|$\)/
+ \ contained
+ \ containedin=cssAttrRegion,sassCssAttribute,lessCssAttribute
- if s:enabled(s:language)
- execute 'syntax include @' . s:language.name . ' syntax/' . get(s:language, 'as', s:language.name) . '.vim'
- unlet! b:current_syntax
+silent! syntax clear cssKeyFrameProp
+syn match cssKeyFrameProp2 /\d*%\|from\|to/
+ \ contained nextgroup=cssDefinition
+ \ containedin=cssAttrRegion,sassCssAttribute,lessCssAttribute
- execute 'syntax region svelte_' . s:language.name
- \ 'keepend'
- \ 'start=/' . s:start . '/'
- \ 'end="</' . s:language.tag . '>"me=s-1'
- \ 'contains=@' . s:language.name . ',svelteSurroundingTag'
- \ 'fold'
- endif
-endfor
+" HTML
+" Clear htmlHead that may cause highlighting out of bounds
+silent! syntax clear htmlHead
-syntax region svelteSurroundingTag contained start=+<\(script\|style\|template\)+ end=+>+ fold contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent
+" JavaScript
+" Number with minus
+syntax match javaScriptNumber '\v<-?\d+L?>|0[xX][0-9a-fA-F]+>'
+ \ containedin=@javascriptSvelteScript display
-" Cybernetically enhanced web apps.
-let b:current_syntax = "svelte"
+" html5 data-*
+syntax match htmlArg '\v<data(-[.a-z0-9]+)+>' containedin=@HTMLSyntax
+"}}}
-" Sync from start because of the wacky nesting.
-syntax sync fromstart
+let b:current_syntax = 'svelte'
+" vim: fdm=marker