" Since vue#Log and vue#GetConfig are always called " in syntax and indent files, " this file will be sourced on opening the first vue file function! s:GetConfig(name, default) let name = 'g:vim_vue_plugin_'.a:name let value = exists(name) ? eval(name) : a:default if a:name == 'config' let value = s:MergeUserConfigIntoDefault(value) endif return value endfunction function! s:MergeUserConfigIntoDefault(user) let default = { \'syntax': { \ 'template': ['html'], \ 'script': ['javascript'], \ 'style': ['css'], \}, \'full_syntax': [], \'initial_indent': [], \'attribute': 0, \'keyword': 0, \'foldexpr': 0, \'debug': 0, \} let user = a:user for key in keys(default) if has_key(user, key) let default[key] = user[key] endif endfor " For backwards compatibility with 'init_indent' if !has_key(user, 'initial_indent') if has_key(user, 'init_indent') \ ? user.init_indent \ : expand('%:e') == 'wpy' let default.initial_indent = ['script', 'style'] endif endif return default endfunction function! s:CheckVersion() if !exists('g:vim_vue_plugin_config') let prev_configs = [ \'g:vim_vue_plugin_load_full_syntax', \'g:vim_vue_plugin_use_pug', \'g:vim_vue_plugin_use_coffee', \'g:vim_vue_plugin_use_typescript', \'g:vim_vue_plugin_use_less', \'g:vim_vue_plugin_use_sass', \'g:vim_vue_plugin_use_scss', \'g:vim_vue_plugin_use_stylus', \'g:vim_vue_plugin_has_init_indent', \'g:vim_vue_plugin_highlight_vue_attr', \'g:vim_vue_plugin_highlight_vue_keyword', \'g:vim_vue_plugin_use_foldexpr', \'g:vim_vue_plugin_custom_blocks', \'g:vim_vue_plugin_debug', \] let has_prev_config = 0 for config in prev_configs if exists(config) let has_prev_config = 1 break endif endfor if has_prev_config let message = 'Hey, it seems that you just upgraded. Please use `g:vim_vue_plugin_config` to replace previous configs' let message2 = 'For details, please check README.md ## Configuration or https://github.com/leafOfTree/vim-vue-plugin' echom '['.s:name.'] '.message echom '['.s:name.'] '.message2 endif endif endfunction function! s:Main() let s:name = 'vim-vue-plugin' let s:config = s:GetConfig('config', {}) let s:full_syntax = s:config.full_syntax let s:debug = s:config.debug call s:CheckVersion() endfunction function! vue#Log(msg) if s:debug echom '['.s:name.'] '.a:msg endif endfunction function! vue#LogWithLnum(msg) if s:debug echom '['.s:name.']['.v:lnum.'] '.a:msg endif endfunction function! vue#Warn(msg) if s:debug echohl WarningMsg echom '['.s:name.'] '.a:msg echohl None endif endfunction function! vue#GetConfig(name, default) return s:GetConfig(a:name, a:default) endfunction if exists('##CursorMoved') && (exists('*OnChangeVueSyntax') || exists('*OnChangeVueSubtype')) augroup vim_vue_plugin autocmd! autocmd CursorMoved,CursorMovedI,WinEnter *.vue,*.wpy \ call s:CheckSyntax() augroup END if exists('*OnChangeVueSyntax') let s:OnChangeListener = function('OnChangeVueSyntax') else let s:OnChangeListener = function('OnChangeVueSubtype') endif let s:syntax = '' function! s:CheckSyntax() let syntax = GetVueSyntax() if s:syntax != syntax call s:OnChangeListener(syntax) let s:syntax = syntax endif endfunction endif function! s:SyntaxListAtEnd(lnum) let plnum = prevnonblank(a:lnum) let pline = getline(plnum) " return [] if prevnonblank is an end tag if pline =~ '^<\/' return [] endif let col = strlen(pline) return map(synstack(plnum, col), 'synIDattr(v:val, "name")') endfunction function! s:SyntaxAtEnd(lnum) let syns = s:SyntaxListAtEnd(a:lnum) let syntax_name = empty(syns) ? '' : get(syns, 0, '') let syntax_name = s:RemoveCssPrefix(syntax_name) return syntax_name endfunction function! vue#SyntaxSecondAtEnd(lnum) let syns = s:SyntaxListAtEnd(a:lnum) return get(syns, 1, '') endfunction function! s:GetBlockTag(lnum) let syntax_name = s:SyntaxAtEnd(a:lnum) let tag = matchstr(syntax_name, '\(\u\U\+\)\+\zeBlock') let tag = substitute(tag, '\U\zs\(\u\)', "-\\1", 'g') let tag = tolower(tag) return tag endfunction let s:style_with_css_prefix = ['scss', 'less', 'stylus'] " Adjust syntax name to support emmet-vim by adding css prefix function! vue#AlterSyntaxForEmmetVim(name, syntax) let name = a:name if count(s:style_with_css_prefix, a:syntax) let name = 'css'.toupper(name[0]).name[1:] endif return name endfunction " Remove css prefix function! s:RemoveCssPrefix(syntax_name) let syntax_name = a:syntax_name let syntax = matchstr(syntax_name, '^\U\+') if syntax == 'css' let next_syntax = tolower(matchstr(syntax_name, '^\U\+\zs\u\U\+')) if count(s:style_with_css_prefix, next_syntax) let syntax_name = matchstr(syntax_name, '^\U\+\zs.*') let syntax_name = tolower(syntax_name[0]).syntax_name[1:] endif endif return syntax_name endfunction function! s:GetBlockSyntax(lnum) let syntax_name = s:SyntaxAtEnd(a:lnum) let syntax = matchstr(syntax_name, '^\U\+') return syntax endfunction function! vue#GetBlockTag(lnum) return s:GetBlockTag(a:lnum) endfunction function! vue#GetBlockSyntax(lnum) return s:GetBlockSyntax(a:lnum) endfunction function! GetVueSubtype() let syntax = vue#GetBlockSyntax(line('.')) return syntax endfunction function! GetVueSyntax() let syntax = vue#GetBlockSyntax(line('.')) return syntax endfunction function! GetVueTag(...) let lnum = a:0 > 0 ? a:1 : line('.') return vue#GetBlockTag(lnum) endfunction function! vue#LoadSyntax(group, syntax) let group = a:group let syntax = a:syntax if s:IncludeOrEqual(s:full_syntax, syntax) call vue#LoadFullSyntax(group, syntax) else let loaded = vue#LoadDefaultSyntax(group, syntax) if !loaded call vue#LoadFullSyntax(group, syntax) endif endif endfunction function! vue#LoadDefaultSyntax(group, syntax) unlet! b:current_syntax let loaded = 0 let syntax_paths = ['$VIMRUNTIME', '$VIM/vimfiles', '$HOME/.vim'] for path in syntax_paths let file = expand(path).'/syntax/'.a:syntax.'.vim' if filereadable(file) let loaded = 1 execute 'syntax include '.a:group.' '.file endif endfor if loaded call vue#Log(a:syntax.': load default') else call vue#Warn(a:syntax.': syntax not found in '.string(syntax_paths)) call vue#Warn(a:syntax.': load full instead') endif return loaded endfunction " Load all syntax files in 'runtimepath' " Useful if there is no default syntax file provided by vim function! vue#LoadFullSyntax(group, syntax) call vue#Log(a:syntax.': load full') call s:SetCurrentSyntax(a:syntax) execute 'syntax include '.a:group.' syntax/'.a:syntax.'.vim' endfunction " Settings to avoid syntax overload function! s:SetCurrentSyntax(type) if a:type == 'coffee' " Avoid `syntax/javascript.vim` in kchmck/vim-coffee-script let b:current_syntax = 'vue' syntax cluster coffeeJS contains=@javascript,@htmlJavaScript else unlet! b:current_syntax endif endfunction function! vue#GetSyntaxList(config_syntax) let syntax_list = [] for syntax in values(a:config_syntax) let type = type(syntax) if type == v:t_string if !count(syntax_list, syntax) call add(syntax_list, syntax) endif elseif type == v:t_list for syn in syntax if !count(syntax_list, syn) call add(syntax_list, syn) endif endfor else echoerr '[vim-vue-plugin] syntax value type' \.' must be either string or list' endif endfor call s:ModifySyntaxOrder(syntax_list) return syntax_list endfunction function! s:IncludeOrEqual(listOrString, item) let listOrString = a:listOrString let item = a:item let type = type(listOrString) return (type == v:t_list && count(listOrString, item)) \ || (type == v:t_string && listOrString == item) endfunction function! vue#IncludeOrEqual(listOrString, item) return s:IncludeOrEqual(a:listOrString, a:item) endfunction function! s:ModifySyntaxOrder(syntax_list) let syntax_list = a:syntax_list " Move basic syntax to the end of the list, so we can check " if they are already loaded by other syntax. " Order matters let load_last = ['html', 'javascript', 'css'] for syntax in load_last let idx = index(syntax_list, syntax) if idx >= 0 call remove(syntax_list, idx) call add(syntax_list, syntax) endif endfor endfunction call s:Main()