Skip to content

Commit 47f1f49

Browse files
AdrianVollmerAdrian Vollmer
andauthored
Add linting support for all formats supported by djlint (#4920)
* Refactor djlint linter code This patch moves the code to the `autoload` directory, so it's available when it's needed by a specific linter. This avoids redundant code when another format supported by djlint is added. * Add linting support for all formats supported by djlint So far, the `djlint` linter in ALE only supported `html`, which is only one of several file types supported by `djlint`. This patch adds support for the following file types: * gohtmltmpl * handlebars * htmlangular * htmldjango * jinja * nunjucks * Add djlint fixer for various HTML template formats * Supported formats: - html - htmlangular - htmldjango - jinja - handlebars - nunjucks - gohtmltmpl * Add doc entries * Add vader tests --------- Co-authored-by: Adrian Vollmer <computerfluesterer@protonmail.com>
1 parent fe6a91f commit 47f1f49

File tree

23 files changed

+448
-38
lines changed

23 files changed

+448
-38
lines changed

ale_linters/gohtmltmpl/djlint.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
" Author: Adrian Vollmer <computerfluesterer@protonmail.com>
2+
" Description: djlint for Django HTML template files
3+
4+
call ale#Set('html_djlint_executable', 'djlint')
5+
call ale#Set('html_djlint_options', '')
6+
7+
call ale#linter#Define('gohtmltmpl', {
8+
\ 'name': 'djlint',
9+
\ 'executable': function('ale#handlers#djlint#GetExecutable'),
10+
\ 'command': function('ale#handlers#djlint#GetCommand'),
11+
\ 'callback': 'ale#handlers#djlint#Handle',
12+
\})

ale_linters/handlebars/djlint.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
" Author: Adrian Vollmer <computerfluesterer@protonmail.com>
2+
" Description: djlint for Django HTML template files
3+
4+
call ale#Set('html_djlint_executable', 'djlint')
5+
call ale#Set('html_djlint_options', '')
6+
7+
call ale#linter#Define('handlebars', {
8+
\ 'name': 'djlint',
9+
\ 'executable': function('ale#handlers#djlint#GetExecutable'),
10+
\ 'command': function('ale#handlers#djlint#GetCommand'),
11+
\ 'callback': 'ale#handlers#djlint#Handle',
12+
\})

ale_linters/html/djlint.vim

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,11 @@
44
call ale#Set('html_djlint_executable', 'djlint')
55
call ale#Set('html_djlint_options', '')
66

7-
function! ale_linters#html#djlint#GetExecutable(buffer) abort
8-
return ale#Var(a:buffer, 'html_djlint_executable')
9-
endfunction
10-
11-
function! ale_linters#html#djlint#GetCommand(buffer) abort
12-
let l:executable = ale_linters#html#djlint#GetExecutable(a:buffer)
13-
14-
let l:options = ale#Var(a:buffer, 'html_djlint_options')
15-
16-
return ale#Escape(l:executable)
17-
\ . (!empty(l:options) ? ' ' . l:options : '') . ' %s'
18-
endfunction
19-
20-
function! ale_linters#html#djlint#Handle(buffer, lines) abort
21-
let l:output = []
22-
let l:pattern = '\v^([A-Z]\d+) (\d+):(\d+) (.*)$'
23-
let l:i = 0
24-
25-
for l:match in ale#util#GetMatches(a:lines, l:pattern)
26-
let l:i += 1
27-
let l:item = {
28-
\ 'lnum': l:match[2] + 0,
29-
\ 'col': l:match[3] + 0,
30-
\ 'vcol': 1,
31-
\ 'text': l:match[4],
32-
\ 'code': l:match[1],
33-
\ 'type': 'W',
34-
\}
35-
call add(l:output, l:item)
36-
endfor
37-
38-
return l:output
39-
endfunction
40-
417
call ale#linter#Define('html', {
428
\ 'name': 'djlint',
43-
\ 'executable': function('ale_linters#html#djlint#GetExecutable'),
44-
\ 'command': function('ale_linters#html#djlint#GetCommand'),
45-
\ 'callback': 'ale_linters#html#djlint#Handle',
9+
\ 'executable': function('ale#handlers#djlint#GetExecutable'),
10+
\ 'command': function('ale#handlers#djlint#GetCommand'),
11+
\ 'callback': 'ale#handlers#djlint#Handle',
4612
\})
4713

4814
" vim:ts=4:sw=4:et:

ale_linters/htmlangular/djlint.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
" Author: Adrian Vollmer <computerfluesterer@protonmail.com>
2+
" Description: djlint for Django HTML template files
3+
4+
call ale#Set('html_djlint_executable', 'djlint')
5+
call ale#Set('html_djlint_options', '')
6+
7+
call ale#linter#Define('htmlangular', {
8+
\ 'name': 'djlint',
9+
\ 'executable': function('ale#handlers#djlint#GetExecutable'),
10+
\ 'command': function('ale#handlers#djlint#GetCommand'),
11+
\ 'callback': 'ale#handlers#djlint#Handle',
12+
\})

ale_linters/htmldjango/djlint.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
" Author: Adrian Vollmer <computerfluesterer@protonmail.com>
2+
" Description: djlint for Django HTML template files
3+
4+
call ale#Set('html_djlint_executable', 'djlint')
5+
call ale#Set('html_djlint_options', '')
6+
7+
call ale#linter#Define('htmldjango', {
8+
\ 'name': 'djlint',
9+
\ 'executable': function('ale#handlers#djlint#GetExecutable'),
10+
\ 'command': function('ale#handlers#djlint#GetCommand'),
11+
\ 'callback': 'ale#handlers#djlint#Handle',
12+
\})

ale_linters/jinja/djlint.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
" Author: Adrian Vollmer <computerfluesterer@protonmail.com>
2+
" Description: djlint for Django HTML template files
3+
4+
call ale#Set('html_djlint_executable', 'djlint')
5+
call ale#Set('html_djlint_options', '')
6+
7+
call ale#linter#Define('jinja', {
8+
\ 'name': 'djlint',
9+
\ 'executable': function('ale#handlers#djlint#GetExecutable'),
10+
\ 'command': function('ale#handlers#djlint#GetCommand'),
11+
\ 'callback': 'ale#handlers#djlint#Handle',
12+
\})

ale_linters/nunjucks/djlint.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
" Author: Adrian Vollmer <computerfluesterer@protonmail.com>
2+
" Description: djlint for Django HTML template files
3+
4+
call ale#Set('html_djlint_executable', 'djlint')
5+
call ale#Set('html_djlint_options', '')
6+
7+
call ale#linter#Define('nunjucks', {
8+
\ 'name': 'djlint',
9+
\ 'executable': function('ale#handlers#djlint#GetExecutable'),
10+
\ 'command': function('ale#handlers#djlint#GetCommand'),
11+
\ 'callback': 'ale#handlers#djlint#Handle',
12+
\})

autoload/ale/fix/registry.vim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ let s:default_registry = {
9898
\ 'suggested_filetypes': ['dhall'],
9999
\ 'description': 'Standard code formatter for the Dhall language and removing dead code',
100100
\ },
101+
\ 'djlint': {
102+
\ 'function': 'ale#fixers#djlint#Fix',
103+
\ 'suggested_filetypes': ['html', 'htmldjango', 'htmlangular', 'jinja', 'handlebars', 'nunjucks', 'gohtmltmpl'],
104+
\ 'description': 'Fix HTML templates with `djlint --reformat`.',
105+
\ },
101106
\ 'dune': {
102107
\ 'function': 'ale#fixers#dune#Fix',
103108
\ 'suggested_filetypes': ['dune'],

autoload/ale/fixers/djlint.vim

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
" Author: Adrian Vollmer (computerfluesterer@protonmail.com)
2+
" Description: HTML template formatter using `djlint --reformat`
3+
4+
call ale#Set('html_djlint_executable', 'djlint')
5+
call ale#Set('html_djlint_use_global', get(g:, 'ale_use_global_executables', 0))
6+
call ale#Set('html_djlint_options', '')
7+
8+
function! ale#fixers#djlint#Fix(buffer) abort
9+
let l:executable = ale#python#FindExecutable(
10+
\ a:buffer,
11+
\ 'html_djlint',
12+
\ ['djlint']
13+
\)
14+
15+
let l:options = ale#Var(a:buffer, 'html_djlint_options')
16+
17+
let l:profile = ''
18+
let l:filetypes = split(getbufvar(a:buffer, '&filetype'), '\.')
19+
20+
" Append the --profile flag depending on the current filetype (unless it's
21+
" already set in g:html_djlint_options).
22+
if match(l:options, '--profile') == -1
23+
let l:djlint_profiles = {
24+
\ 'html': 'html',
25+
\ 'htmldjango': 'django',
26+
\ 'jinja': 'jinja',
27+
\ 'nunjucks': 'nunjucks',
28+
\ 'handlebars': 'handlebars',
29+
\ 'gohtmltmpl': 'golang',
30+
\ 'htmlangular': 'angular',
31+
\}
32+
33+
for l:filetype in l:filetypes
34+
if has_key(l:djlint_profiles, l:filetype)
35+
let l:profile = l:djlint_profiles[l:filetype]
36+
break
37+
endif
38+
endfor
39+
endif
40+
41+
if !empty(l:profile)
42+
let l:options = (!empty(l:options) ? l:options . ' ' : '') . '--profile ' . l:profile
43+
endif
44+
45+
return {
46+
\ 'command': ale#Escape(l:executable) . ' --reformat ' . l:options . ' -',
47+
\}
48+
endfunction

autoload/ale/handlers/djlint.vim

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
" Author: Vivian De Smedt <vds2212@gmail.com>, Adrian Vollmer <computerfluesterer@protonmail.com>
2+
" Description: Adds support for djlint
3+
"
4+
function! ale#handlers#djlint#GetExecutable(buffer) abort
5+
return ale#Var(a:buffer, 'html_djlint_executable')
6+
endfunction
7+
8+
function! ale#handlers#djlint#GetCommand(buffer) abort
9+
let l:executable = ale#handlers#djlint#GetExecutable(a:buffer)
10+
11+
let l:options = ale#Var(a:buffer, 'html_djlint_options')
12+
13+
let l:profile = ''
14+
let l:filetypes = split(getbufvar(a:buffer, '&filetype'), '\.')
15+
16+
" Append the --profile flag depending on the current filetype (unless it's
17+
" already set in g:html_djlint_options).
18+
if match(l:options, '--profile') == -1
19+
let l:djlint_profiles = {
20+
\ 'html': 'html',
21+
\ 'htmldjango': 'django',
22+
\ 'jinja': 'jinja',
23+
\ 'nunjucks': 'nunjucks',
24+
\ 'handlebars': 'handlebars',
25+
\ 'gohtmltmpl': 'golang',
26+
\ 'htmlangular': 'angular',
27+
\}
28+
29+
for l:filetype in l:filetypes
30+
if has_key(l:djlint_profiles, l:filetype)
31+
let l:profile = l:djlint_profiles[l:filetype]
32+
break
33+
endif
34+
endfor
35+
endif
36+
37+
if !empty(l:profile)
38+
let l:options = (!empty(l:options) ? l:options . ' ' : '') . '--profile ' . l:profile
39+
endif
40+
41+
return ale#Escape(l:executable)
42+
\ . (!empty(l:options) ? ' ' . l:options : '') . ' %s'
43+
endfunction
44+
45+
function! ale#handlers#djlint#Handle(buffer, lines) abort
46+
let l:output = []
47+
let l:pattern = '\v^([A-Z]\d+) (\d+):(\d+) (.*)$'
48+
let l:i = 0
49+
50+
for l:match in ale#util#GetMatches(a:lines, l:pattern)
51+
let l:i += 1
52+
let l:item = {
53+
\ 'lnum': l:match[2] + 0,
54+
\ 'col': l:match[3] + 0,
55+
\ 'vcol': 1,
56+
\ 'text': l:match[4],
57+
\ 'code': l:match[1],
58+
\ 'type': 'W',
59+
\}
60+
call add(l:output, l:item)
61+
endfor
62+
63+
return l:output
64+
endfunction

0 commit comments

Comments
 (0)