html5.vim icon indicating copy to clipboard operation
html5.vim copied to clipboard

Wrong indentation for custom elements without hyphens

Open dnd opened this issue 7 years ago • 3 comments

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.

dnd avatar Nov 29 '18 16:11 dnd

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'

ycmjason avatar Jan 05 '19 11:01 ycmjason

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.

othree avatar Jan 08 '19 06:01 othree

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

andbar-ru avatar Jul 10 '21 08:07 andbar-ru