From 86026411e5312b02ead026afd7e95df629bc104d Mon Sep 17 00:00:00 2001 From: yemai Date: Thu, 27 Sep 2018 16:57:32 +0800 Subject: [PATCH] init --- after/ftplugin/vue.vim | 1 + after/indent/vue.vim | 114 +++++++++++++++++++++++++++++++++++++++++ after/syntax/vue.vim | 78 ++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 after/ftplugin/vue.vim create mode 100644 after/indent/vue.vim create mode 100644 after/syntax/vue.vim diff --git a/after/ftplugin/vue.vim b/after/ftplugin/vue.vim new file mode 100644 index 0000000..aa9c91d --- /dev/null +++ b/after/ftplugin/vue.vim @@ -0,0 +1 @@ +setlocal suffixesadd+=.vue diff --git a/after/indent/vue.vim b/after/indent/vue.vim new file mode 100644 index 0000000..5a9a8c5 --- /dev/null +++ b/after/indent/vue.vim @@ -0,0 +1,114 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Vim indent file +" +" Language: JSX (JavaScript) +" Maintainer: Max Wang +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" Save the current JavaScript indentexpr. +let b:jsx_js_indentexpr = &indentexpr + +" Prologue; load in XML indentation. +if exists('b:did_indent') + let s:did_indent=b:did_indent + unlet b:did_indent +endif +exe 'runtime! indent/xml.vim' +if exists('s:did_indent') + let b:did_indent=s:did_indent +endif + +setlocal indentexpr=GetJsxIndent() + +" JS indentkeys +setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e +" XML indentkeys +setlocal indentkeys+=*,<>>,<<>,/ + +" Multiline end tag regex (line beginning with '>' or '/>') +let s:endtag = '^\s*\/\?>\s*;\=' + +" Get all syntax types at the beginning of a given line. +fu! SynSOL(lnum) + return map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') +endfu + +" Get all syntax types at the end of a given line. +fu! SynEOL(lnum) + let lnum = prevnonblank(a:lnum) + let col = strlen(getline(lnum)) + return map(synstack(lnum, col), 'synIDattr(v:val, "name")') +endfu + +" Check if a syntax attribute is XMLish. +fu! SynAttrXMLish(synattr) + return a:synattr =~ "^xml" || a:synattr =~ "^jsx" +endfu + +" Check if a synstack is XMLish (i.e., has an XMLish last attribute). +fu! SynXMLish(syns) + return SynAttrXMLish(get(a:syns, -1)) +endfu + +" Check if a synstack denotes the end of a JSX block. +fu! SynJSXBlockEnd(syns) + return get(a:syns, -1) =~ '\%(js\|javascript\)Braces' && + \ SynAttrXMLish(get(a:syns, -2)) +endfu + +" Determine how many jsxRegions deep a synstack is. +fu! SynJSXDepth(syns) + return len(filter(copy(a:syns), 'v:val ==# "jsxRegion"')) +endfu + +" Check whether `cursyn' continues the same jsxRegion as `prevsyn'. +fu! SynJSXContinues(cursyn, prevsyn) + let curdepth = SynJSXDepth(a:cursyn) + let prevdepth = SynJSXDepth(a:prevsyn) + + " In most places, we expect the nesting depths to be the same between any + " two consecutive positions within a jsxRegion (e.g., between a parent and + " child node, between two JSX attributes, etc.). The exception is between + " sibling nodes, where after a completed element (with depth N), we return + " to the parent's nesting (depth N - 1). This case is easily detected, + " since it is the only time when the top syntax element in the synstack is + " jsxRegion---specifically, the jsxRegion corresponding to the parent. + return prevdepth == curdepth || + \ (prevdepth == curdepth + 1 && get(a:cursyn, -1) ==# 'jsxRegion') +endfu + +" Cleverly mix JS and XML indentation. +fu! GetJsxIndent() + let cursyn = SynSOL(v:lnum) + let prevsyn = SynEOL(v:lnum - 1) + + " Use XML indenting iff: + " - the syntax at the end of the previous line was either JSX or was the + " closing brace of a jsBlock whose parent syntax was JSX; and + " - the current line continues the same jsxRegion as the previous line. + if (SynXMLish(prevsyn) || SynJSXBlockEnd(prevsyn)) && + \ SynJSXContinues(cursyn, prevsyn) + let ind = XmlIndentGet(v:lnum, 0) + + " Align '/>' and '>' with '<' for multiline tags. + if getline(v:lnum) =~? s:endtag + let ind = ind - &sw + endif + + " Then correct the indentation of any JSX following '/>' or '>'. + if getline(v:lnum - 1) =~? s:endtag + let ind = ind + &sw + endif + else + if len(b:jsx_js_indentexpr) + " Invoke the base JS package's custom indenter. (For vim-javascript, + " e.g., this will be GetJavascriptIndent().) + let ind = eval(b:jsx_js_indentexpr) + else + let ind = cindent(v:lnum) + endif + endif + + return ind +endfu diff --git a/after/syntax/vue.vim b/after/syntax/vue.vim new file mode 100644 index 0000000..6707cec --- /dev/null +++ b/after/syntax/vue.vim @@ -0,0 +1,78 @@ +echom 'vim for vue' +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Vim syntax file +" +" Language: Vue (JavaScript) +" Maintainer: leafOfTree +" Depends: pangloss/vim-javascript +" +" CREDITS: Inspired by mxw/vim-jsx. +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" load in XML syntax. +if exists('b:current_syntax') + let s:current_syntax=b:current_syntax + unlet b:current_syntax +endif +syn include @XMLSyntax syntax/xml.vim +if exists('s:current_syntax') + let b:current_syntax=s:current_syntax +endif + +" load in HTML syntax +if exists('b:current_syntax') + let s:current_syntax=b:current_syntax + unlet b:current_syntax +endif +syn include @HTMLSyntax syntax/css.vim +if exists('s:current_syntax') + let b:current_syntax=s:current_syntax +endif + +" load in CSS syntax +if exists('b:current_syntax') + let s:current_syntax=b:current_syntax + unlet b:current_syntax +endif +syn include @CSSSyntax syntax/javascript.vim +if exists('s:current_syntax') + let b:current_syntax=s:current_syntax +endif + +" Find tag + keepend contains=@jsAll,jsImport,jsExport,@XMLSyntax +syn region vueStyle contained start=++ end=++ keepend contains=@CSSSyntax + +" Officially, vim-jsx depends on the pangloss/vim-javascript syntax package +" (and is tested against it exclusively). However, in practice, we make some +" effort towards compatibility with other packages. +" +" These are the plugin-to-syntax-element correspondences: +" +" - pangloss/vim-javascript: jsBlock, jsExpression +" - jelera/vim-javascript-syntax: javascriptBlock +" - othree/yajs.vim: javascriptNoReserved + + +" Vue attributes should color as JS. Note the trivial end pattern; we let +" jsBlock take care of ending the region. +syn region xmlString contained start=+{+ end=++ contains=jsBlock,javascriptBlock + +" Note that we prohibit Vue tags from having a < or word character immediately +" preceding it, to avoid conflicts with, respectively, the left shift operator +" and generic Flow type annotations (http://flowtype.org/). +syn region vueRegion + \ contains=@Spell,@XMLSyntax,jsBlock,javascriptBlock,vueScript,vueStyle + \ start=+\%(<\|\w\)\@[:,]\@!\)\([^>]*>(\)\@!+ + \ skip=++ + \ end=++ + \ end=+/>+ + \ keepend + \ extend +" +" Add vueRegion to the lowest-level JS syntax cluster. +syn cluster jsExpression add=vueRegion + +" Allow vueRegion to contain reserved words. +syn cluster javascriptNoReserved add=vueRegion