diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2015-07-18 22:50:09 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2015-07-18 22:50:09 +0200 |
commit | 1c80c4bb08ae250d2eb19aabe0f31c1b2bdf5097 (patch) | |
tree | c7700e4cb18952201fb991a48fb727ba3b9d4287 /after/indent/jsx.vim | |
parent | 548653cafeaa948161ad9ac8184deca0bff95537 (diff) | |
download | vim-polyglot-1c80c4bb08ae250d2eb19aabe0f31c1b2bdf5097.tar.gz vim-polyglot-1c80c4bb08ae250d2eb19aabe0f31c1b2bdf5097.zip |
Add jsx support, closes #56
Diffstat (limited to 'after/indent/jsx.vim')
-rw-r--r-- | after/indent/jsx.vim | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/after/indent/jsx.vim b/after/indent/jsx.vim new file mode 100644 index 00000000..d0b4d4ef --- /dev/null +++ b/after/indent/jsx.vim @@ -0,0 +1,98 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Vim indent file +" +" Language: JSX (JavaScript) +" Maintainer: Max Wang <mxawng@gmail.com> +" Depends: pangloss/vim-javascript +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" Do nothing if we don't find the @jsx pragma (and we care). +exec 'source '.fnameescape(expand('<sfile>:p:h:h').'/jsx-config.vim') +if g:jsx_pragma_required && !b:jsx_pragma_found | finish | endif + +" Do nothing if we don't have the .jsx extension (and we care). +if g:jsx_ext_required && !exists('b:jsx_ext_found') | finish | endif + +" 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+=*<Return>,<>>,<<>,/ + +" Self-closing tag regex. +let s:sctag = '^\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 has any XMLish attribute. +fu! SynXMLishAny(syns) + for synattr in a:syns + if SynAttrXMLish(synattr) + return 1 + endif + endfor + return 0 +endfu + +" Check if a synstack denotes the end of a JSX block. +fu! SynJSXBlockEnd(syns) + return get(a:syns, -1) == 'jsBraces' && SynAttrXMLish(get(a:syns, -2)) +endfu + +" Cleverly mix JS and XML indentation. +fu! GetJsxIndent() + let cursyn = SynSOL(v:lnum) + let prevsyn = SynEOL(v:lnum - 1) + + " Use XML indenting if 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. + if (SynXMLish(prevsyn) || SynJSXBlockEnd(prevsyn)) && SynXMLishAny(cursyn) + let ind = XmlIndentGet(v:lnum, 0) + + " Align '/>' with '<' for multiline self-closing tags. + if getline(v:lnum) =~? s:sctag + let ind = ind - &sw + endif + + " Then correct the indentation of any JSX following '/>'. + if getline(v:lnum - 1) =~? s:sctag + let ind = ind + &sw + endif + else + let ind = GetJavascriptIndent() + endif + + return ind +endfu |