]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0551: filetype: htmlangular files are not properly detected v9.1.0551
authorDennis van den Berg <dennis.vandenberg@nedap.com>
Tue, 9 Jul 2024 17:25:33 +0000 (19:25 +0200)
committerChristian Brabandt <cb@256bit.org>
Tue, 9 Jul 2024 17:44:32 +0000 (19:44 +0200)
Problem:  filetype: htmlangular files are not properly detected
Solution: Use the new htmlangular filetype for angular files, because
          since angular v17, those are no longer valid HTML files.
          (Dennis van den Berg)

Since Angular 17, the new Control Flow Syntax is not valid HTML. This PR
adds a new filetype detection for the HTML templates of Angular.

It first checks the filename. The Angular convention is to use
*.component.html for the template. However, this is not mandatory.

If the filename does not match, it will check the contents of the file
if it contains:

  - One of the Control-Flow blocks: @if, @for, @switch, @defer
  - A structural directive: *ngIf, *ngFor, *ngSwitch, *ngTemplateOutlet
  - Builtin Angular elements: ng-template or ng-content
  - String interpolation: {{ something }}

This enables the Angular LSP to attach only to htmlangular filetypes, as
well as language parsers, such as tree-sitter.

closes: #15190

Signed-off-by: Dennis van den Berg <dennis.vandenberg@nedap.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/autoload/dist/ft.vim
runtime/ftplugin/htmlangular.vim [new file with mode: 0644]
src/testdir/test_filetype.vim
src/version.c

index 2e93dd0d579992e8292f87332259e5922c62cf2f..1a4195a9de2f527c5a6a40405d3624f17c268dd4 100644 (file)
@@ -402,14 +402,29 @@ export def FTharedoc()
   endif
 enddef
 
-# Distinguish between HTML, XHTML and Django
+# Distinguish between HTML, XHTML, Django and Angular
 export def FThtml()
   var n = 1
+
+  # Test if the filename follows the Angular component template convention
+  if expand('%:t') =~ '^.*\.component\.html$'
+    setf htmlangular
+    return
+  endif
+
   while n < 40 && n <= line("$")
+    # Check for Angular
+    if getline(n) =~ '@\(if\|for\|defer\|switch\)\|\*\(ngIf\|ngFor\|ngSwitch\|ngTemplateOutlet\)\|ng-template\|ng-content\|{{.*}}'
+      setf htmlangular
+      return
+    endif
+
+    # Check for XHTML
     if getline(n) =~ '\<DTD\s\+XHTML\s'
       setf xhtml
       return
     endif
+    # Check for Django
     if getline(n) =~ '{%\s*\(autoescape\|block\|comment\|csrf_token\|cycle\|debug\|extends\|filter\|firstof\|for\|if\|ifchanged\|include\|load\|lorem\|now\|query_string\|regroup\|resetcycle\|spaceless\|templatetag\|url\|verbatim\|widthratio\|with\)\>\|{#\s\+'
       setf htmldjango
       return
diff --git a/runtime/ftplugin/htmlangular.vim b/runtime/ftplugin/htmlangular.vim
new file mode 100644 (file)
index 0000000..b181b20
--- /dev/null
@@ -0,0 +1,12 @@
+" Vim filetype plugin file
+" Language: Angular HTML Template
+" Maintainer: Dennis van den Berg <dennis@vdberg.dev>
+" Last Change: 2024 Jul 8
+
+" Only use this filetype plugin when no other was loaded.
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Use HTML and Angular template ftplugins
+runtime! ftplugin/html.vim
index 2a9e6b4580ef80844211f39e33019f14752bf9ad..379f6a1fa01167e49822a83fdfffd50015d2e77d 100644 (file)
@@ -334,7 +334,8 @@ def s:GetFilenameChecks(): dict<list<string>>
     hoon: ['file.hoon'],
     hostconf: ['/etc/host.conf', 'any/etc/host.conf'],
     hostsaccess: ['/etc/hosts.allow', '/etc/hosts.deny', 'any/etc/hosts.allow', 'any/etc/hosts.deny'],
-    html: ['file.html', 'file.htm', 'file.cshtml', 'file.component.html'],
+    html: ['file.html', 'file.htm', 'file.cshtml'],
+    htmlangular: ['file.component.html'],
     htmlm4: ['file.html.m4'],
     httest: ['file.htt', 'file.htb'],
     hurl: ['file.hurl'],
@@ -1046,7 +1047,8 @@ func Test_emptybuf_ftdetect()
   call assert_equal('', &filetype)
   filetype detect
   call assert_equal('sh', &filetype)
-  close!
+  " close the swapfile
+  bw!
 endfunc
 
 " Test for ':filetype indent on' and ':filetype indent off' commands
@@ -1570,6 +1572,41 @@ func Test_hook_file()
   filetype off
 endfunc
 
+func Test_html_file()
+  filetype on
+
+  " HTML Angular
+  let content = ['@for (item of items; track item.name) {', '  <li> {{ item.name }}</li>', '} @empty {', '  <li> There are no items.</li>', '}']
+  call writefile(content, 'Xfile.html', 'D')
+  split Xfile.html
+  call assert_equal('htmlangular', &filetype)
+  bwipe!
+
+  " Django Template
+  let content = ['{% if foobar %}',
+      \ '    <ul>',
+      \ '    {% for question in list %}',
+      \ '        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>',
+      \ '    {% endfor %}',
+      \ '    </ul>',
+      \ '{% else %}',
+      \ '    <p>No polls are available.</p>',
+      \ '{% endif %}']
+  call writefile(content, 'Xfile.html', 'D')
+  split Xfile.html
+  call assert_equal('htmldjango', &filetype)
+  bwipe!
+
+  " regular HTML
+  let content = ['<!DOCTYPE html>', '<html>', '    <head>Foobar</head>', '    <body>Content', '    </body>', '</html>']
+  call writefile(content, 'Xfile.html', 'D')
+  split Xfile.html
+  call assert_equal('html', &filetype)
+  bwipe!
+
+  filetype off
+endfunc
+
 func Test_m_file()
   filetype on
 
index caa779ce53b7b43e5048be886c306ab060b48b63..b745bd0e2b51154136078cb6185cc674c86d75d5 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    551,
 /**/
     550,
 /**/