mirror of
https://github.com/leafOfTree/vim-vue-plugin.git
synced 2025-12-08 21:54:46 +08:00
Refactor the whole plugin
This commit is contained in:
433
syntax/vue.vim
433
syntax/vue.vim
@@ -1,306 +1,167 @@
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Vim syntax file
|
||||
"
|
||||
" Language: Vue
|
||||
" Maintainer: leaf <leafvocation@gmail.com>
|
||||
"
|
||||
" CREDITS: Inspired by mxw/vim-jsx.
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
if exists("b:current_syntax") && b:current_syntax == 'vue'
|
||||
if exists('b:current_syntax') && b:current_syntax == 'vue'
|
||||
finish
|
||||
endif
|
||||
|
||||
" For advanced users, this variable can be used to avoid overload
|
||||
let b:current_loading_main_syntax = 'vue'
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
"
|
||||
" Config {{{
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
let s:use_pug = vue#GetConfig("use_pug", 0)
|
||||
let s:use_less = vue#GetConfig("use_less", 0)
|
||||
let s:use_sass = vue#GetConfig("use_sass", 0)
|
||||
let s:use_scss = vue#GetConfig("use_scss", 0)
|
||||
let s:use_stylus = vue#GetConfig("use_stylus", 0)
|
||||
let s:use_coffee = vue#GetConfig("use_coffee", 0)
|
||||
let s:use_typescript = vue#GetConfig("use_typescript", 0)
|
||||
"}}}
|
||||
" <sfile> is replaced with the file name of the sourced file
|
||||
let s:patch_path = expand('<sfile>:p:h').'/patch'
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
"
|
||||
" Load main syntax {{{
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
function! s:Init()
|
||||
""" Configs
|
||||
let s:config = vue#GetConfig('config', {})
|
||||
let s:config_syntax = s:config.syntax
|
||||
|
||||
" Load syntax/html.vim to syntax group, which loads full JavaScript and CSS
|
||||
" syntax. It defines group @html, @htmlJavaScript, and @htmlCss.
|
||||
call vue#LoadSyntax('@html', 'html')
|
||||
" For advanced users, it can be used to avoid overload
|
||||
let b:current_loading_main_syntax = 'vue'
|
||||
endfunction
|
||||
|
||||
" Avoid overload
|
||||
if !hlexists('cssTagName')
|
||||
call vue#LoadSyntax('@htmlCss', 'css')
|
||||
endif
|
||||
function! s:GetGroupNameForLoading(syntax)
|
||||
return '@'.a:syntax
|
||||
endfunction
|
||||
|
||||
" Avoid overload
|
||||
if !hlexists('javaScriptComment')
|
||||
call vue#Log('load javascript cluster')
|
||||
call vue#LoadSyntax('@htmlJavaScript', 'javascript')
|
||||
endif
|
||||
|
||||
" Load vue-html syntax
|
||||
runtime syntax/vue-html.vim
|
||||
|
||||
" Load vue-javascript syntax
|
||||
runtime syntax/vue-javascript.vim
|
||||
"}}}
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
"
|
||||
" Load pre-processors syntax {{{
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" If pug is enabled, load vim-pug syntax
|
||||
if s:use_pug
|
||||
call vue#LoadFullSyntax('@PugSyntax', 'pug')
|
||||
syn cluster htmlJavascript remove=javascriptParenthesisBlock
|
||||
endif
|
||||
|
||||
" If less is enabled, load less syntax
|
||||
if s:use_less
|
||||
call vue#LoadSyntax('@LessSyntax', 'less')
|
||||
runtime! after/syntax/less.vim
|
||||
endif
|
||||
|
||||
" If sass is enabled, load sass syntax
|
||||
if s:use_sass
|
||||
call vue#LoadSyntax('@SassSyntax', 'sass')
|
||||
runtime! after/syntax/sass.vim
|
||||
endif
|
||||
|
||||
" If scss is enabled, load sass syntax
|
||||
if s:use_scss
|
||||
call vue#LoadSyntax('@ScssSyntax', 'scss')
|
||||
runtime! after/syntax/scss.vim
|
||||
endif
|
||||
|
||||
" If stylus is enabled, load stylus syntax
|
||||
if s:use_stylus
|
||||
call vue#LoadFullSyntax('@StylusSyntax', 'stylus')
|
||||
runtime! after/syntax/stylus.vim
|
||||
endif
|
||||
|
||||
" If CoffeeScript is enabled, load the syntax. Keep name consistent with
|
||||
" vim-coffee-script/after/html.vim
|
||||
if s:use_coffee
|
||||
call vue#LoadFullSyntax('@htmlCoffeeScript', 'coffee')
|
||||
endif
|
||||
|
||||
" If TypeScript is enabled, load the syntax.
|
||||
if s:use_typescript
|
||||
call vue#LoadFullSyntax('@TypeScript', 'typescript')
|
||||
endif
|
||||
"}}}
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
"
|
||||
" Syntax highlight {{{
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" All start with html/javascript/css for emmet-vim in-file type detection
|
||||
syntax region htmlVueTemplate fold
|
||||
\ start=+<template[^>]*>+
|
||||
\ end=+^</template>+
|
||||
\ keepend contains=@html
|
||||
" When template code is not well indented
|
||||
syntax region htmlVueTemplate fold
|
||||
\ start=+<template[^>]*>+
|
||||
\ end=+</template>\ze\n\(^$\n\)*<\(script\|style\)+
|
||||
\ keepend contains=@html
|
||||
|
||||
syntax region javascriptVueScript fold
|
||||
\ start=+<script[^>]*>+
|
||||
\ end=+</script>+
|
||||
\ keepend contains=@htmlJavaScript,jsImport,jsExport,vueTag
|
||||
|
||||
|
||||
syntax region cssVueStyle fold
|
||||
\ start=+<style[^>]*>+
|
||||
\ end=+</style>+
|
||||
\ keepend contains=@htmlCss,vueTag
|
||||
|
||||
" Preprocessors syntax
|
||||
syntax region pugVueTemplate fold
|
||||
\ start=+<template[^>]*lang=["']pug["'][^>]*>+
|
||||
\ end=+</template>+
|
||||
\ keepend contains=@PugSyntax,vueTag
|
||||
|
||||
syntax region coffeeVueScript fold
|
||||
\ start=+<script[^>]*lang=["']coffee["'][^>]*>+
|
||||
\ end=+</script>+
|
||||
\ keepend contains=@htmlCoffeeScript,jsImport,jsExport,vueTag
|
||||
|
||||
syntax region typescriptVueScript fold
|
||||
\ start=+<script[^>]*lang=["']ts["'][^>]*>+
|
||||
\ end=+</script>+
|
||||
\ keepend contains=@TypeScript,vueTag
|
||||
|
||||
syntax region cssLessVueStyle fold
|
||||
\ start=+<style[^>]*lang=["']less["'][^>]*>+
|
||||
\ end=+</style>+
|
||||
\ keepend contains=@LessSyntax,vueTag
|
||||
syntax region sassVueStyle fold
|
||||
\ start=+<style[^>]*lang=["']sass["'][^>]*>+
|
||||
\ end=+</style>+
|
||||
\ keepend contains=@SassSyntax,vueTag
|
||||
syntax region cssScssVueStyle fold
|
||||
\ start=+<style[^>]*lang=["']scss["'][^>]*>+
|
||||
\ end=+</style>+
|
||||
\ keepend contains=@ScssSyntax,vueTag
|
||||
|
||||
" Backward compatiable for `use_sass` option
|
||||
if s:use_sass && !s:use_scss
|
||||
syntax region cssScssVueStyle fold
|
||||
\ start=+<style[^>]*lang=["']scss["'][^>]*>+
|
||||
\ end=+</style>+
|
||||
\ keepend contains=@SassSyntax,vueTag
|
||||
endif
|
||||
|
||||
syntax region cssStylusVueStyle fold
|
||||
\ start=+<style[^>]*lang=["']stylus["'][^>]*>+
|
||||
\ end=+</style>+
|
||||
\ keepend contains=@StylusSyntax,vueTag
|
||||
|
||||
syntax region vueTag fold
|
||||
\ start=+^<[^/]+ end=+>+ skip=+></+
|
||||
\ contained contains=htmlTagN,htmlString,htmlArg
|
||||
syntax region vueTag
|
||||
\ start=+^</+ end=+>+
|
||||
\ contains=htmlTagN,htmlString,htmlArg
|
||||
|
||||
highlight default link vueTag htmlTag
|
||||
highlight default link cssUnitDecorators2 Number
|
||||
highlight default link cssKeyFrameProp2 Constant
|
||||
"}}}
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
"
|
||||
" Custom blocks {{{
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
runtime syntax/vue-custom-blocks.vim
|
||||
"}}}
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
"
|
||||
" Syntax patch {{{
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Patch 7.4.1142
|
||||
if has("patch-7.4-1142")
|
||||
if has("win32")
|
||||
syntax iskeyword @,48-57,_,128-167,224-235,$,-
|
||||
else
|
||||
syntax iskeyword @,48-57,_,192-255,$,-
|
||||
" Extend group name as
|
||||
" html defines group @htmlJavaScript and @htmlCss.
|
||||
" coffee defines group @coffeeJS.
|
||||
function! s:GetGroupNameForHighlight(syntax)
|
||||
let syntax = a:syntax
|
||||
let name = '@'.a:syntax
|
||||
if syntax == 'javascript'
|
||||
let name = '@javascript,@htmlJavaScript,@coffeeJS'
|
||||
elseif syntax == 'css'
|
||||
let name = '@css,@htmlCss'
|
||||
endif
|
||||
else
|
||||
setlocal iskeyword+=-
|
||||
endif
|
||||
return name
|
||||
endfunction
|
||||
|
||||
" Style
|
||||
" Redefine (less|sass|stylus)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=cssLessVueStyle
|
||||
\ start="{" end="}"
|
||||
endif
|
||||
if s:use_sass
|
||||
silent! syntax clear sassDefinition
|
||||
syntax region sassDefinition matchgroup=cssBraces
|
||||
\ contains=@SassSyntax,sassDefinition
|
||||
\ contained containedin=sassVueStyle
|
||||
\ start="{" end="}"
|
||||
function! s:GetSynatxName(block, syntax)
|
||||
let block = a:block
|
||||
let syntax = a:syntax
|
||||
let name = syntax.toupper(block[0]).block[1:].'Block'
|
||||
let name = vue#AlterSyntaxForEmmetVim(name, syntax)
|
||||
return name
|
||||
endfunction
|
||||
|
||||
" Extend to highlight all numbers in expression
|
||||
syntax match cssValueNumber
|
||||
\ /\W\zs\d\+\(\.\d\+\)\?%\?\ze\W/
|
||||
\ contained containedin=sassDefinition
|
||||
endif
|
||||
" If not loading https://github.com/cakebaker/scss-syntax.vim
|
||||
if s:use_scss && !hlexists('scssNestedProperty')
|
||||
silent! syntax clear scssDefinition
|
||||
syntax region cssScssDefinition transparent matchgroup=cssBraces
|
||||
\ contains=@ScssSyntax,cssScssDefinition
|
||||
\ contained containedin=cssScssVueStyle
|
||||
\ start="{" end="}"
|
||||
function! s:LoadSyntaxList(syntax_list)
|
||||
for syntax in a:syntax_list
|
||||
let loaded = s:BeforeLoadSyntax(syntax)
|
||||
if !loaded
|
||||
let syntax_group = s:GetGroupNameForLoading(syntax)
|
||||
call vue#LoadSyntax(syntax_group, syntax)
|
||||
endif
|
||||
call s:AfterLoadSyntax(syntax)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Extend to highlight all numbers in expression
|
||||
syntax match cssValueNumber
|
||||
\ /\W\zs\d\+\(\.\d\+\)\?%\?\ze\W/
|
||||
\ contained containedin=cssScssDefinition
|
||||
endif
|
||||
if s:use_stylus
|
||||
silent! syntax clear stylusDefinition
|
||||
syntax region cssStylusDefinition matchgroup=cssBraces
|
||||
\ contains=@StylusSyntax,cssStylusDefinition
|
||||
\ contained containedin=cssStylusVueStyle
|
||||
\ start="{" end="}"
|
||||
endif
|
||||
" For specific syntax, we need to handle it specially
|
||||
function! s:BeforeLoadSyntax(syntax)
|
||||
let syntax = a:syntax
|
||||
|
||||
" Use a different name in order to avoid css syntax interference
|
||||
silent! syntax clear cssUnitDecorators
|
||||
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,stylusCssAttribute
|
||||
" Avoid overload if group already exists
|
||||
let loaded = 0
|
||||
if syntax == 'javascript'
|
||||
let loaded = hlexists('javaScriptComment')
|
||||
elseif syntax == 'css'
|
||||
let loaded = hlexists('cssTagName')
|
||||
endif
|
||||
return loaded
|
||||
endfunction
|
||||
|
||||
silent! syntax clear cssKeyFrameProp
|
||||
syn match cssKeyFrameProp2 /\d*%\|from\|to/
|
||||
\ contained nextgroup=cssDefinition
|
||||
\ containedin=cssAttrRegion,sassCssAttribute,lessCssAttribute,stylusCssAttribute
|
||||
function! s:AfterLoadSyntax(syntax)
|
||||
let syntax = a:syntax
|
||||
call s:LoadPatchSyntax(syntax)
|
||||
call s:LoadStyleAfterSyntax(syntax)
|
||||
endfunction
|
||||
|
||||
" Coffee
|
||||
if s:use_coffee
|
||||
silent! syntax clear coffeeConstant
|
||||
syn match coffeeConstant '\v<\u\C[A-Z0-9_]+>' display
|
||||
\ containedin=@coffeeIdentifier
|
||||
endif
|
||||
function! s:LoadPatchSyntax(syntax)
|
||||
let file = s:patch_path.'/'.a:syntax.'.vim'
|
||||
if filereadable(file)
|
||||
execute 'syntax include '.file
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" JavaScript
|
||||
" Number with minus
|
||||
syntax match javaScriptNumber '\v<-?\d+L?>|0[xX][0-9a-fA-F]+>'
|
||||
\ containedin=@javascriptVueScript display
|
||||
function! s:LoadStyleAfterSyntax(syntax)
|
||||
let syntax = a:syntax
|
||||
if count(['scss', 'sass', 'less', 'stylus'], syntax) == 1
|
||||
execute 'runtime! after/syntax/'.syntax.'.vim'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" HTML
|
||||
" Clear htmlHead that may cause highlighting out of bounds
|
||||
silent! syntax clear htmlHead
|
||||
function! s:GetSyntaxLangName(syntax)
|
||||
let syntax = a:syntax
|
||||
if syntax == 'typescript'
|
||||
let syntax = 'ts'
|
||||
endif
|
||||
return syntax
|
||||
endfunction
|
||||
|
||||
" html5 data-*
|
||||
syntax match htmlArg '\v<data(-[.a-z0-9]+)+>' containedin=@html
|
||||
"}}}
|
||||
function! s:SetSyntax(block, syntax, lang)
|
||||
let block = a:block
|
||||
let syntax = a:syntax
|
||||
let lang = a:lang
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
"
|
||||
" Syntax sync {{{
|
||||
"
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
syntax sync clear
|
||||
syntax sync minlines=100
|
||||
syntax sync match vueHighlight groupthere NONE "</\(script\|template\|style\)"
|
||||
syntax sync match scriptHighlight groupthere javascriptVueScript "<script"
|
||||
syntax sync match scriptHighlight groupthere coffeeVueScript "<script[^>]*lang=["']coffee["'][^>]*>"
|
||||
syntax sync match scriptHighlight groupthere typescriptVueScript "<script[^>]*lang=["']ts["'][^>]*>"
|
||||
syntax sync match templateHighlight groupthere htmlVueTemplate "<template"
|
||||
syntax sync match templateHighlight groupthere pugVueTemplate "<template[^>]*lang=["']pug["'][^>]*>"
|
||||
syntax sync match styleHighlight groupthere cssVueStyle "<style"
|
||||
syntax sync match styleHighlight groupthere cssLessVueStyle "<style[^>]*lang=["']less["'][^>]*>"
|
||||
syntax sync match styleHighlight groupthere sassVueStyle "<style[^>]*lang=["']sass["'][^>]*>"
|
||||
syntax sync match styleHighlight groupthere cssScssVueStyle "<style[^>]*lang=["']scss["'][^>]*>"
|
||||
syntax sync match styleHighlight groupthere cssStylusVueStyle "<style[^>]*lang=["']stylus["'][^>]*>"
|
||||
"}}}
|
||||
let name = s:GetSynatxName(block, syntax)
|
||||
let syntax_lang_name = s:GetSyntaxLangName(syntax)
|
||||
let syntax_lang = lang ? 'lang=["'']'.syntax_lang_name.'["''][^>]*' : ''
|
||||
let start = '<'.block.'[^>]*'.syntax_lang.'>'
|
||||
let end = '</'.block.'>'
|
||||
let syntax_group = s:GetGroupNameForHighlight(syntax)
|
||||
|
||||
execute 'syntax region '.name.' fold '
|
||||
\.' start=+'.start.'+'
|
||||
\.' end=+'.end.'+'
|
||||
\.' keepend contains='.syntax_group.', vueTag'
|
||||
endfunction
|
||||
|
||||
function! s:SetBlockSyntax(config_syntax)
|
||||
for [block, syntax] in items(a:config_syntax)
|
||||
let type = type(syntax)
|
||||
if type == v:t_string
|
||||
call s:SetSyntax(block, syntax, 0)
|
||||
elseif type == v:t_list && len(syntax)
|
||||
call s:SetSyntax(block, syntax[0], 0)
|
||||
for syn in syntax
|
||||
call s:SetSyntax(block, syn, 1)
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:HighlightVueTag()
|
||||
syntax region vueTag fold
|
||||
\ start=+^<[^/]+ end=+>+ skip=+></+
|
||||
\ contained contains=htmlTagN,htmlString,htmlArg
|
||||
syntax region vueTag
|
||||
\ start=+^</+ end=+>+
|
||||
\ contained contains=htmlTagN,htmlString,htmlArg
|
||||
highlight default link vueTag htmlTag
|
||||
endfunction
|
||||
|
||||
function! s:SetSyntaxSync()
|
||||
syntax sync fromstart
|
||||
endfunction
|
||||
|
||||
function! s:SetIsKeyword()
|
||||
if has("patch-7.4-1142")
|
||||
if has("win32")
|
||||
syntax iskeyword @,48-57,_,128-167,224-235,$,-
|
||||
else
|
||||
syntax iskeyword @,48-57,_,192-255,$,-
|
||||
endif
|
||||
else
|
||||
setlocal iskeyword+=-
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! VimVuePluginSyntaxMain(id)
|
||||
call s:Init()
|
||||
let syntax_list = vue#GetSyntaxList(s:config_syntax)
|
||||
call s:LoadSyntaxList(syntax_list)
|
||||
call s:SetBlockSyntax(s:config_syntax)
|
||||
call s:SetSyntaxSync()
|
||||
call s:SetIsKeyword()
|
||||
call s:HighlightVueTag()
|
||||
endfunction
|
||||
|
||||
" call timer_start(10, 'VimVuePluginSyntaxMain')
|
||||
call VimVuePluginSyntaxMain(0)
|
||||
|
||||
let b:current_syntax = 'vue'
|
||||
" vim: fdm=marker
|
||||
|
||||
Reference in New Issue
Block a user