Wrong indentation for custom elements without hyphens
I'm experiencing incorrect indentation when a custom element does not contain a hyphen. It is nesting the child content even with the tag.
<div>
| <!-- correct indent -->
</div>
<w-hatever>
| <!-- correct indent -->
</w-hatever>
<Cust-om>
| <!-- correct indent -->
</Cust-om>
<whatever>
| <!-- incorrect indent -->
</whatever>
<Custom>
| <!-- incorrect indent -->
</Custom>
I know that technically single word element names are not to spec, but they are very common now in frameworks such as Vue, and it would be nice if the html5.vim plugin just nested any element correctly regardless of name. Vue in particular specifies pascal cased names rather than kebab-cased in its default linting rules.
I have submitted a PR for this. Meanwhile u can install from my repo for that functionality.
https://github.com/ycmjason/html5.vim
Plug 'ycmjason/html5.vim'
I will try to fix this again. In my memory, last time I want to fix this is trying to use the indent tag list. But I forgot the detail now.
One quick workaround is by setting the variable html_indent_inctags.
ex:
let g:html_indent_inctags = 'custom,ele'
Buffer variable also works too.
There are some issues with indenting PascalCase custom tags (e.g. <VCardText>), because they are being processed in lower case in indent/html.vim. We need avoid situation when all tags (body, html, div and others) will be treated as custom tags in indent file. We may consider tag is custom if it is not included in all tags. I have patched builtin indent/html.vim of vim version 8.2.3114 on my machine.
vim_indent_html.patch
--- html.vim.orig 2021-07-10 11:39:05.794503656 +0300
+++ html.vim 2021-07-10 11:43:50.485987774 +0300
@@ -239,10 +239,28 @@
\ 'svg', 'time', 'video'])
" Tags added for web components:
call s:AddITags(s:indent_tags, [
\ 'content', 'shadow', 'template'])
+
+" According to https://developer.mozilla.org/en-US/docs/Web/HTML/Element
+let s:all_tags = {}
+call s:AddITags(s:all_tags, [
+ \ 'a', 'abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio', 'b', 'base',
+ \ 'basefont', 'bdi', 'bdo', 'bgsound', 'big', 'blink', 'blockquote', 'body', 'br', 'button',
+ \ 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data',
+ \ 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'embed',
+ \ 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2',
+ \ 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'image',
+ \ 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'main', 'map',
+ \ 'mark', 'marquee', 'math', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'nobr', 'noembed',
+ \ 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param',
+ \ 'picture', 'plaintext', 'portal', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby',
+ \ 's', 'samp', 'script', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer',
+ \ 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody',
+ \ 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt',
+ \ 'u', 'ul', 'var', 'video', 'wbr', 'xmp'])
"}}}
" Add Block Tags: these contain alien content
"{{{
call s:AddBlockTag('pre', 2)
@@ -368,12 +386,16 @@
" Used by s:CheckTag().
func s:CheckCustomTag(ctag)
"{{{
" Returns 1 if ctag is the tag for a custom element, 0 otherwise.
" a:ctag can be "tag" or "/tag" or "<!--" or "-->"
- let pattern = '\%\(\w\+-\)\+\w\+'
- if match(a:ctag, pattern) == -1
+ " Tags like VCustomTag is custom too. Here ctag is in lower case (vcustomtag),
+ " so we consider it custom if it consists of letters only and it isn't in s:all_tags.
+ let pattern1 = '\%\(\w\+-\)\+\w\+' " custom-tag, /custom-tag
+ let pattern2 = '^/\?\w\+$' " customtag, /customtag
+ let is_custom_tag = match(a:ctag, pattern1) != -1 || (match(a:ctag, pattern2) == 0 && get(s:all_tags, a:ctag) == 0)
+ if !is_custom_tag
return 0
endif
if matchstr(a:ctag, '\/\ze.\+') == "/"
" closing tag
if s:block != 0