diff --git a/ale_linters/html/djlint.vim b/ale_linters/html/djlint.vim
new file mode 100644
index 00000000..c9cbbd2b
--- /dev/null
+++ b/ale_linters/html/djlint.vim
@@ -0,0 +1,48 @@
+" Author: Vivian De Smedt
+" Description: Adds support for djlint
+
+call ale#Set('html_djlint_executable', 'djlint')
+call ale#Set('html_djlint_options', '')
+
+function! ale_linters#html#djlint#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'html_djlint_executable')
+endfunction
+
+function! ale_linters#html#djlint#GetCommand(buffer) abort
+ let l:executable = ale_linters#html#djlint#GetExecutable(a:buffer)
+
+ let l:options = ale#Var(a:buffer, 'html_djlint_options')
+
+ return ale#Escape(l:executable)
+ \ . (!empty(l:options) ? ' ' . l:options : '') . ' %s'
+endfunction
+
+function! ale_linters#html#djlint#Handle(buffer, lines) abort
+ let l:output = []
+ let l:pattern = '\v^([A-Z]\d+) (\d+):(\d+) (.*)$'
+ let l:i = 0
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:i += 1
+ let l:item = {
+ \ 'lnum': l:match[2] + 0,
+ \ 'col': l:match[3] + 0,
+ \ 'vcol': 1,
+ \ 'text': l:match[4],
+ \ 'code': l:match[1],
+ \ 'type': 'W',
+ \}
+ call add(l:output, l:item)
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('html', {
+\ 'name': 'djlint',
+\ 'executable': function('ale_linters#html#djlint#GetExecutable'),
+\ 'command': function('ale_linters#html#djlint#GetCommand'),
+\ 'callback': 'ale_linters#html#djlint#Handle',
+\})
+
+" vim:ts=4:sw=4:et:
diff --git a/doc/ale-html.txt b/doc/ale-html.txt
index 189a7ed0..de6cf3af 100644
--- a/doc/ale-html.txt
+++ b/doc/ale-html.txt
@@ -33,6 +33,25 @@ cspell *ale-html-cspell*
See |ale-cspell-options|
+===============================================================================
+djlint *ale-html-djlint*
+
+g:ale_html_djlint_executable *g:ale_html_djlint_executable*
+ *b:ale_html_djlint_executable*
+ Type: |String|
+ Default: `'djlint'`
+
+ See |ale-integrations-local-executables|
+
+
+g:ale_html_djlint_options *g:ale_html_djlint_options*
+ *b:ale_html_djlint_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be changed to modify flags given to djlint.
+
+
===============================================================================
fecs *ale-html-fecs*
diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt
index 063fc36f..d5f3d9f0 100644
--- a/doc/ale-supported-languages-and-tools.txt
+++ b/doc/ale-supported-languages-and-tools.txt
@@ -274,6 +274,7 @@ Notes:
* `alex`
* `angular`
* `cspell`
+ * djlint
* `eslint`
* `fecs`
* `html-beautify`
diff --git a/doc/ale.txt b/doc/ale.txt
index 94d6d3b3..b0154f59 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -3106,6 +3106,7 @@ documented in additional help files.
html....................................|ale-html-options|
angular...............................|ale-html-angular|
cspell................................|ale-html-cspell|
+ djlint................................|ale-html-djlint|
fecs..................................|ale-html-fecs|
html-beautify.........................|ale-html-beautify|
htmlhint..............................|ale-html-htmlhint|
diff --git a/supported-tools.md b/supported-tools.md
index 5f8efde7..60ae27be 100644
--- a/supported-tools.md
+++ b/supported-tools.md
@@ -283,6 +283,7 @@ formatting.
* [alex](https://github.com/get-alex/alex)
* [angular](https://www.npmjs.com/package/@angular/language-server)
* [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell)
+ * [djlint](https://www.djlint.com/)
* [eslint](https://github.com/BenoitZugmeyer/eslint-plugin-html)
* [fecs](http://fecs.baidu.com/)
* [html-beautify](https://beautifier.io/)
diff --git a/test/handler/test_djlint_handler.vader b/test/handler/test_djlint_handler.vader
new file mode 100644
index 00000000..5729f669
--- /dev/null
+++ b/test/handler/test_djlint_handler.vader
@@ -0,0 +1,21 @@
+Before:
+ runtime ale_linters/html/djlint.vim
+
+After:
+ call ale#linter#Reset()
+
+Execute(The Djlint handler should parse output with a column correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 47,
+ \ 'vcol': 1,
+ \ 'col': 8,
+ \ 'code': 'H008',
+ \ 'text': 'Attributes should be double quoted.',
+ \ 'type': 'W'
+ \ }
+ \ ],
+ \ ale_linters#html#djlint#Handle(0, [
+ \ 'H008 47:8 Attributes should be double quoted.'
+ \ ])
diff --git a/test/linter/test_djlint.vader b/test/linter/test_djlint.vader
new file mode 100644
index 00000000..6d1a0d80
--- /dev/null
+++ b/test/linter/test_djlint.vader
@@ -0,0 +1,14 @@
+Before:
+ call ale#assert#SetUpLinterTest('html', 'djlint')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The default djlint command should be correct):
+ AssertLinter 'djlint', ale#Escape('djlint') . ' %s'
+
+Execute(The executable should be configurable):
+ let g:ale_html_djlint_executable = 'foo bar'
+ let g:ale_html_djlint_options = '--option'
+
+ AssertLinter 'foo bar', ale#Escape('foo bar') . ' --option %s'