Change svelte provider, fixes #700

This commit is contained in:
Adam Stankiewicz
2021-04-14 12:11:13 +02:00
parent 5de7022bcb
commit 067e07e137
8 changed files with 870 additions and 267 deletions

View File

@@ -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) - [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) - [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) - [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-indent](https://github.com/jasonshell/vim-svg-indent)
- [svg](https://github.com/vim-scripts/svg.vim) (SVG syntax highlighting for svg files) - [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) - [swift](https://github.com/keith/swift.vim) (Swift syntax highlighting for swift files)

71
autoload/svelte.vim Normal file
View File

@@ -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

View File

@@ -2,46 +2,24 @@ if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'ftplugin/svelte.vim
finish finish
endif endif
" Vim filetype plugin if exists("b:did_ftplugin") | finish | endif
" 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
let b:did_ftplugin = 1 let b:did_ftplugin = 1
" Matchit support if !has('nvim')
if exists('loaded_matchit') && !exists('b:match_words') setlocal matchpairs+=<:>
let b:match_ignorecase = 0 endif
" In order: if exists("loaded_matchit")
" let b:match_ignorecase = 1
" 1. Svelte control flow keywords. let b:match_words = '<:>,' .
" 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\)\>,' .
\ '{:},' .
\ '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' . \ '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' .
\ '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' . \ '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' .
\ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>' \ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>,' .
\ '{#\(if\|each\)[^}]*}:{\:else[^}]*}:{\/\(if\|each\)},' .
\ '{#await[^}]*}:{\:then[^}]*}:{\/await},'
endif endif
" ALE fixing and linting. " Indent correctly with template string for vim-javascript/builtin
if exists('g:loaded_ale') " indentexpr
if !exists('b:ale_fixers') let b:syng_str = '^\%(.*template\)\@!.*string\|special'
let b:ale_fixers = ['eslint', 'prettier', 'prettier_standard'] let b:syng_strcom = '^\%(.*template\)\@!.*string\|comment\|regex\|special\|doc'
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

131
ftplugin/svelte/fold.vim Normal file
View File

@@ -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

View File

@@ -2,160 +2,301 @@ if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'indent/svelte.vim')
finish finish
endif endif
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Vim indent file " Vim indent file
" Language: Svelte 3 (HTML/JavaScript) "
" Author: Evan Lecklider <evan@lecklider.com> " Language: Svelte
" Maintainer: Evan Lecklide <evan@lecklider.com> " Maintainer: leafOfTree <leafvocation@gmail.com>
" URL: https://github.com/evanleck/vim-svelte "
" CREDITS: Inspired by mxw/vim-jsx.
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if exists("b:did_indent") if exists("b:did_indent")
finish finish
endif 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*$'
"}}}
if !exists('g:svelte_indent_style') """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:svelte_indent_style = 1 "
endif " 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)
"}}}
" Try to mirror Svelte's indent settings so the HTML indenting scripts match. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if g:svelte_indent_script "
let b:html_indent_script1 = "inc" " Load indent method {{{
else "
let b:html_indent_script1 = "zero" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
endif " Save shiftwidth
let s:sw = &sw
if g:svelte_indent_style " Use lib/indent/ files for compatibility
let b:html_indent_style1 = "inc"
else
let b:html_indent_style1 = "zero"
endif
runtime! indent/html.vim
unlet! b:did_indent unlet! b:did_indent
runtime lib/indent/xml.vim
let s:html_indent = &l:indentexpr unlet! b:did_indent
let b:did_indent = 1 runtime lib/indent/css.vim
setlocal indentexpr=GetSvelteIndent() " Use normal indent files
setlocal indentkeys=o,O,*<Return>,<>>,{,},0),0],!^F,;,=:else,=:then,=:catch,=/if,=/each,=/await unlet! b:did_indent
runtime! indent/javascript.vim
let b:javascript_indentexpr = &indentexpr
" Only define the function once. if s:use_pug
if exists('*GetSvelteIndent') unlet! b:did_indent
finish let s:save_formatoptions = &formatoptions
runtime! indent/pug.vim
let &formatoptions = s:save_formatoptions
endif endif
if s:use_sass
unlet! b:did_indent
runtime! indent/sass.vim
endif
if s:use_coffee
unlet! b:did_indent
runtime! indent/coffee.vim
endif
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()
"}}}
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"
" Functions {{{
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! GetSvelteIndent() function! GetSvelteIndent()
let current_line_number = v:lnum let prevlnum = prevnonblank(v:lnum-1)
let prevline = getline(prevlnum)
let prevsyns = s:SynsSOL(prevlnum)
if current_line_number == 0 let curline = getline(v:lnum)
return 0 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 endif
let current_line = getline(current_line_number) if s:IsBlockStart(prevsyns) && prevline !~ s:oneline_block
call s:Log('increase block indent')
" Opening script and style tags should be all the way outdented. let ind = ind + &sw
if current_line =~ '^\s*</\?\(script\|style\)'
return 0
endif endif
let previous_line_number = prevnonblank(current_line_number - 1) if s:IsBlockEnd(cursyns, curline)
let previous_line = getline(previous_line_number) call s:Log('decrease block indent')
let previous_line_indent = indent(previous_line_number) let ind = ind - &sw
endif
" The inside of scripts an styles should be indented unless disabled. " Align '/>' and '>' with '<' for multiline tags.
if previous_line =~ '^\s*<script' if curline =~? s:tag_end
if g:svelte_indent_script let ind = ind - &sw
return previous_line_indent + shiftwidth() 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 else
return previous_line_indent call s:Log('syntax: javascript')
endif if len(b:javascript_indentexpr)
endif let ind = eval(b:javascript_indentexpr)
if previous_line =~ '^\s*<style'
if g:svelte_indent_style
return previous_line_indent + shiftwidth()
else else
return previous_line_indent let ind = cindent(v:lnum)
endif endif
endif endif
execute "let indent = " . s:html_indent if curline =~? s:svelte_tag_start || curline =~? s:svelte_tag_end
\|| prevline =~? s:svelte_tag_end
" For some reason, the HTML CSS indentation keeps indenting the next line over \|| (curline =~ s:template_tag && s:SynPug(cursyn))
" and over after each style declaration. call s:Log('current line is svelte tag or previous line is svelte tag end')
if searchpair('<style>', '', '</style>', 'bW') && previous_line =~ ';$' && current_line !~ '}' call s:Log('... or current line is pug template tag')
return previous_line_indent 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 endif
" "/await" or ":catch" or ":then" call s:Log('indent: '.ind)
if current_line =~ '^\s*{\s*\/await' || current_line =~ '^\s*{\s*:\(catch\|then\)' return ind
let await_start = searchpair('{\s*#await\>', '', '{\s*\/await\>', 'bW')
if await_start
return indent(await_start)
endif
endif
" "/each"
if current_line =~ '^\s*{\s*\/each'
let each_start = searchpair('{\s*#each\>', '', '{\s*\/each\>', 'bW')
if each_start
return indent(each_start)
endif
endif
" "/if"
if current_line =~ '^\s*{\s*\/if'
let if_start = searchpair('{\s*#if\>', '', '{\s*\/if\>', 'bW')
if if_start
return indent(if_start)
endif
endif
" ":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')
" 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
" "#if" or "#each"
if previous_line =~ '^\s*{\s*#\(if\|each\|await\)'
return previous_line_indent + shiftwidth()
endif
" ":else" or ":then"
if previous_line =~ '^\s*{\s*:\(else\|catch\|then\)'
return previous_line_indent + shiftwidth()
endif
" 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
endif
endif
return indent
endfunction endfunction
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
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
function! s:SynsEOL(lnum)
let lnum = prevnonblank(a:lnum)
let col = strlen(getline(lnum))
return map(synstack(lnum, col), 'synIDattr(v:val, "name")')
endfunction
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
function! s:SynHTML(syn)
return a:syn ==? 'htmlSvelteTemplate'
endfunction
function! s:SynBlockBody(syn)
return a:syn ==? 'svelteBlockBody'
endfunction
function! s:SynBlockStart(syn)
return a:syn ==? 'svelteBlockStart'
endfunction
function! s:SynBlockEnd(syn)
return a:syn ==? 'svelteBlockEnd'
endfunction
function! s:SynPug(syn)
return a:syn ==? 'pugSvelteTemplate'
endfunction
function! s:SynCoffee(syn)
return a:syn ==? 'coffeeSvelteScript'
endfunction
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
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
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

View File

@@ -1574,7 +1574,7 @@ filetypes:
- stylus - stylus
--- ---
name: svelte name: svelte
remote: evanleck/vim-svelte@main remote: leafOfTree/vim-svelte-plugin
filetypes: filetypes:
- name: svelte - name: svelte
linguist: Svelte linguist: Svelte

127
syntax/svelte-html.vim Normal file
View File

@@ -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

View File

@@ -2,123 +2,278 @@ if polyglot#init#is_disabled(expand('<sfile>:p'), 'svelte', 'syntax/svelte.vim')
finish finish
endif endif
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Vim syntax file " 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 " Language: Svelte
" is tested against it exclusively). If you're using vim-polyglot, then you're " Maintainer: leaf <leafvocation@gmail.com>
" all set. "
" CREDITS: Inspired by mxw/vim-jsx.
if exists("b:current_syntax") "
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if exists("b:current_syntax") && b:current_syntax == 'svelte'
finish finish
endif endif
" Read HTML to begin with. " For advanced users, this variable can be used to avoid overload
runtime! syntax/html.vim let b:current_loading_main_syntax = 'svelte'
unlet! b:current_syntax """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Expand HTML tag names to include mixed case, periods, and colons.
syntax match htmlTagName contained "\<[a-zA-Z:\.]*\>"
" 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
" The "slot" attribute has special meaning.
syntax keyword svelteKeyword slot contained containedin=htmlTag
" 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
" 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
" 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
" Inline keywords.
syntax match svelteKeyword "@html" contained containedin=jsBlock,javascriptBlock
syntax match svelteKeyword "@debug" contained containedin=jsBlock,javascriptBlock
" Repeat functions.
syntax match svelteRepeat "#each" contained containedin=jsBlock,javascriptBlock
syntax match svelteRepeat "/each" contained containedin=jsBlock,javascriptBlock
highlight def link svelteConditional Conditional
highlight def link svelteKeyword Keyword
highlight def link svelteRepeat Repeat
" 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 " Config {{{
" @davidroeca (thank you!). "
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
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)
"}}}
" 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) " Functions {{{
" 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')) function! s:LoadSyntax(group, type)
return 0 if s:load_full_syntax
endif call s:LoadFullSyntax(a:group, a:type)
" 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
else else
return 0 call s:LoadDefaultSyntax(a:group, a:type)
endif endif
endfunction endfunction
" Default tag definitions. function! s:LoadDefaultSyntax(group, type)
let s:languages = [ unlet! b:current_syntax
\ { 'name': 'less', 'tag': 'style' }, let syntaxPaths = ['$VIMRUNTIME', '$VIM/vimfiles', '$HOME/.vim']
\ { 'name': 'scss', 'tag': 'style' }, for path in syntaxPaths
\ { 'name': 'sass', 'tag': 'style' }, let file = expand(path).'/syntax/'.a:type.'.vim'
\ { 'name': 'stylus', 'tag': 'style' }, if filereadable(file)
\ { 'name': 'typescript', 'tag': 'script' }, execute 'syntax include '.a:group.' '.file
\ ] endif
endfor
endfunction
" Add global tag definitions to our defaults. function! s:LoadFullSyntax(group, type)
if exists('g:svelte_preprocessor_tags') && type(g:svelte_preprocessor_tags) == v:t_list call s:SetCurrentSyntax(a:type)
let s:languages += g:svelte_preprocessor_tags exec 'syntax include '.a:group.' syntax/'.a:type.'.vim'
endfunction
" Settings to avoid syntax overload
function! s:SetCurrentSyntax(type)
if a:type == 'coffee'
syntax cluster coffeeJS contains=@htmlJavaScript
" Avoid overload of `javascript.vim`
let b:current_syntax = 'svelte'
else
unlet! b:current_syntax
endif
endfunction
"}}}
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"
" 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')
" Load svelte-html syntax
syntax include syntax/svelte-html.vim
" Avoid overload
if !hlexists('cssTagName')
call s:LoadSyntax('@htmlCss', 'css')
endif endif
for s:language in s:languages " Avoid overload
let s:attr = '\(lang\|type\)=\("\|''\)[^\2]*' . s:language.name . '[^\2]*\2' if !hlexists('javaScriptComment')
let s:start = '<' . s:language.tag . '\>\_[^>]*' . s:attr . '\_[^>]*>' call s:LoadSyntax('@htmlJavaScript', 'javascript')
endif
"}}}
if s:enabled(s:language) """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
execute 'syntax include @' . s:language.name . ' syntax/' . get(s:language, 'as', s:language.name) . '.vim' "
unlet! b:current_syntax " Load pre-processors syntax {{{
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" If pug is enabled, load vim-pug syntax
if s:use_pug
call s:LoadFullSyntax('@PugSyntax', 'pug')
endif
execute 'syntax region svelte_' . s:language.name " If less is enabled, load less syntax
\ 'keepend' if s:use_less
\ 'start=/' . s:start . '/' call s:LoadSyntax('@LessSyntax', 'less')
\ 'end="</' . s:language.tag . '>"me=s-1' runtime! after/syntax/less.vim
\ 'contains=@' . s:language.name . ',svelteSurroundingTag' endif
\ 'fold'
" 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
syn iskeyword @,48-57,_,192-255,$
endif endif
endfor endif
syntax region svelteSurroundingTag contained start=+<\(script\|style\|template\)+ end=+>+ fold contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent " 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
" Cybernetically enhanced web apps. " Avoid css syntax interference
let b:current_syntax = "svelte" 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
" Sync from start because of the wacky nesting. silent! syntax clear cssKeyFrameProp
syntax sync fromstart syn match cssKeyFrameProp2 /\d*%\|from\|to/
\ contained nextgroup=cssDefinition
\ containedin=cssAttrRegion,sassCssAttribute,lessCssAttribute
" HTML
" Clear htmlHead that may cause highlighting out of bounds
silent! syntax clear htmlHead
" JavaScript
" Number with minus
syntax match javaScriptNumber '\v<-?\d+L?>|0[xX][0-9a-fA-F]+>'
\ containedin=@javascriptSvelteScript display
" html5 data-*
syntax match htmlArg '\v<data(-[.a-z0-9]+)+>' containedin=@HTMLSyntax
"}}}
let b:current_syntax = 'svelte'
" vim: fdm=marker