Fix indentation for script tags and refactor

Fixes the indentation for script tags. The javascript indentation
interpreted the `<script>` tag as a comparison operator.
This commit is contained in:
Adriaan Zonnenberg
2017-03-26 13:36:09 +02:00
parent 239401d54d
commit d4793f5963
2 changed files with 112 additions and 22 deletions

View File

@@ -3,39 +3,62 @@
" Maintainer: Eduardo San Martin Morote
" Author: Adriaan Zonnenberg
if exists("b:did_indent")
if exists('b:did_indent')
finish
endif
" Load indent files for required languages
for language in ['stylus', 'pug', 'css', 'javascript', 'html', 'coffee']
function! s:get_indentexpr(language)
unlet! b:did_indent
exe "runtime! indent/".language.".vim"
exe "let s:".language."indent = &indentexpr"
execute 'runtime! indent/' . a:language . '.vim'
return &indentexpr
endfunction
" The order is important here, tags without attributes go last.
" HTML is left out, it will be used when there is no match.
let s:languages = [
\ { 'name': 'pug', 'pairs': ['<template lang="pug"', '</template>'] },
\ { 'name': 'stylus', 'pairs': ['<style lang="stylus"', '</style>'] },
\ { 'name': 'css', 'pairs': ['<style', '</style>'] },
\ { 'name': 'coffee', 'pairs': ['<script lang="coffee"', '</script>'] },
\ { 'name': 'javascript', 'pairs': ['<script', '</script>'] },
\ ]
for language in s:languages
" Set 'indentexpr' if the user has an indent file installed for the language
if strlen(globpath(&rtp, 'indent/'. language.name .'.vim'))
let language.indentexpr = s:get_indentexpr(language.name)
endif
endfor
let s:html_indent = s:get_indentexpr('html')
let b:did_indent = 1
setlocal indentexpr=GetVueIndent()
if exists("*GetVueIndent")
if exists('*GetVueIndent')
finish
endif
function! GetVueIndent()
if searchpair('<template lang="pug"', '', '</template>', 'bWr')
exe "let indent = ".s:pugindent
elseif searchpair('<style lang="stylus"', '', '</style>', 'bWr')
exe "let indent = ".s:stylusindent
elseif searchpair('<style', '', '</style>', 'bWr')
exe "let indent = ".s:cssindent
elseif searchpair('<script lang="coffee"', '', '</script>', 'bWr')
exe "let indent = ".s:coffeeindent
elseif searchpair('<script', '', '</script>', 'bWr')
exe "let indent = ".s:javascriptindent
for language in s:languages
let opening_tag_line = searchpair(language.pairs[0], '', language.pairs[1], 'bWr')
if opening_tag_line
execute 'let indent = ' . get(language, 'indentexpr', -1)
break
endif
endfor
if exists('l:indent')
if (opening_tag_line == prevnonblank(v:lnum - 1) || opening_tag_line == v:lnum)
\ || getline(v:lnum) =~ '\v^\s*\</(script|style|template)'
return 0
endif
else
exe "let indent = ".s:htmlindent
" Couldn't find language, fall back to html
execute 'let indent = ' . s:html_indent
endif
return indent > -1 ? indent : s:htmlindent
return indent
endfunction

View File

@@ -8,7 +8,7 @@ Given vue (An unindented html template):
</div>
</template>
Do:
Do (Indent the whole buffer):
gg=G
Expect (The html template got indented):
@@ -18,6 +18,28 @@ Expect (The html template got indented):
</div>
</template>
Given vue (Template tag inside a template):
<template>
<div>
<template v-if="loading">
Loading...
</template>
</div>
</template>
Do (Indent the whole buffer):
gg=G
Expect (It didn't get unindented):
<template>
<div>
<template v-if="loading">
Loading...
</template>
</div>
</template>
#
# JavaScript
#
@@ -35,8 +57,7 @@ Given vue (An unindented JavaScript region):
Do (Indent the whole buffer):
gg=G
Expect vue (TODO):
* TODO: fix the indent script to exclude the surrounding html tag
Expect vue (The JavaScript region got indented):
<script>
export default {
methods: {
@@ -57,7 +78,7 @@ Given vue (An unindented css region):
}
</style>
Do:
Do (Indent the whole buffer):
gg=G
Expect vue (The css region got indented):
@@ -66,3 +87,49 @@ Expect vue (The css region got indented):
background: tomato;
}
</style>
#
# Pug
#
Given vue (Empty Pug region):
<template lang="pug">
</template>
Do (Insert list items):
o
ul\<CR>
li Item A\<CR>
li Item B
Expect:
<template lang="pug">
ul
li Item A
li Item B
</template>
#
# Stylus
#
Given vue (Empty Stylus region):
<style lang="stylus">
</style>
Do (Insert some styles):
o
body\<CR>
font-size: 14px\<CR>
\<CR>\<C-d>
h1\<CR>
font-size: 30px\<CR>
display: block
Expect:
<style lang="stylus">
body
font-size: 14px
h1
font-size: 30px
display: block
</style>