1
0
mirror of https://github.com/amix/vimrc synced 2025-07-13 06:35:01 +08:00

Updated plugins

This commit is contained in:
Amir
2024-10-06 10:25:50 +02:00
parent ee7e062909
commit 46294d589d
202 changed files with 306918 additions and 203617 deletions

View File

@ -35,22 +35,94 @@ function! ale#definition#UpdateTagStack() abort
endif
endfunction
function! ale#definition#FormatTSServerResponse(response_item, options) abort
if get(a:options, 'open_in') is# 'quickfix'
return {
\ 'filename': a:response_item.file,
\ 'lnum': a:response_item.start.line,
\ 'col': a:response_item.start.offset,
\}
else
return {
\ 'filename': a:response_item.file,
\ 'line': a:response_item.start.line,
\ 'column': a:response_item.start.offset,
\}
endif
endfunction
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
if has_key(a:response, 'request_seq')
\&& has_key(s:go_to_definition_map, a:response.request_seq)
let l:options = remove(s:go_to_definition_map, a:response.request_seq)
if get(a:response, 'success', v:false) is v:true && !empty(a:response.body)
let l:filename = a:response.body[0].file
let l:line = a:response.body[0].start.line
let l:column = a:response.body[0].start.offset
let l:item_list = []
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options)
for l:response_item in a:response.body
call add(
\ l:item_list,
\ ale#definition#FormatTSServerResponse(l:response_item, l:options)
\)
endfor
if empty(l:item_list)
call ale#util#Execute('echom ''No definitions found''')
elseif len(l:item_list) == 1
let l:filename = l:item_list[0].filename
if get(l:options, 'open_in') is# 'quickfix'
let l:line = l:item_list[0].lnum
let l:column = l:item_list[0].col
else
let l:line = l:item_list[0].line
let l:column = l:item_list[0].column
endif
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options)
else
if get(l:options, 'open_in') is# 'quickfix'
call setqflist([], 'r')
call setqflist(l:item_list, 'a')
call ale#util#Execute('cc 1')
else
call ale#definition#UpdateTagStack()
call ale#preview#ShowSelection(l:item_list, l:options)
endif
endif
endif
endif
endfunction
function! ale#definition#FormatLSPResponse(response_item, options) abort
if has_key(a:response_item, 'targetUri')
" LocationLink items use targetUri
let l:uri = a:response_item.targetUri
let l:line = a:response_item.targetRange.start.line + 1
let l:column = a:response_item.targetRange.start.character + 1
else
" LocationLink items use uri
let l:uri = a:response_item.uri
let l:line = a:response_item.range.start.line + 1
let l:column = a:response_item.range.start.character + 1
endif
if get(a:options, 'open_in') is# 'quickfix'
return {
\ 'filename': ale#util#ToResource(l:uri),
\ 'lnum': l:line,
\ 'col': l:column,
\}
else
return {
\ 'filename': ale#util#ToResource(l:uri),
\ 'line': l:line,
\ 'column': l:column,
\}
endif
endfunction
function! ale#definition#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:go_to_definition_map, a:response.id)
@ -65,21 +137,29 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
let l:result = []
endif
for l:item in l:result
if has_key(l:item, 'targetUri')
" LocationLink items use targetUri
let l:uri = l:item.targetUri
let l:line = l:item.targetRange.start.line + 1
let l:column = l:item.targetRange.start.character + 1
else
" LocationLink items use uri
let l:uri = l:item.uri
let l:line = l:item.range.start.line + 1
let l:column = l:item.range.start.character + 1
endif
let l:item_list = []
for l:response_item in l:result
call add(l:item_list,
\ ale#definition#FormatLSPResponse(l:response_item, l:options)
\)
endfor
if empty(l:item_list)
call ale#util#Execute('echom ''No definitions found''')
elseif len(l:item_list) == 1
call ale#definition#UpdateTagStack()
let l:uri = ale#util#ToURI(l:item_list[0].filename)
if get(l:options, 'open_in') is# 'quickfix'
let l:line = l:item_list[0].lnum
let l:column = l:item_list[0].col
else
let l:line = l:item_list[0].line
let l:column = l:item_list[0].column
endif
let l:uri_handler = ale#uri#GetURIHandler(l:uri)
if l:uri_handler is# v:null
@ -88,9 +168,16 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
else
call l:uri_handler.OpenURILink(l:uri, l:line, l:column, l:options, a:conn_id)
endif
break
endfor
else
if get(l:options, 'open_in') is# 'quickfix'
call setqflist([], 'r')
call setqflist(l:item_list, 'a')
call ale#util#Execute('cc 1')
else
call ale#definition#UpdateTagStack()
call ale#preview#ShowSelection(l:item_list, l:options)
endif
endif
endif
endfunction

View File

@ -37,6 +37,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['bib'],
\ 'description': 'Format bib files using bibclean.',
\ },
\ 'biome': {
\ 'function': 'ale#fixers#biome#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'jsonc'],
\ 'description': 'Fix JavaScript and TypeScript using biome.',
\ },
\ 'black': {
\ 'function': 'ale#fixers#black#Fix',
\ 'suggested_filetypes': ['python'],
@ -98,6 +103,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
\ 'description': 'Apply fecs format to a file.',
\ },
\ 'hurlfmt': {
\ 'function': 'ale#fixers#hurlfmt#Fix',
\ 'suggested_filetypes': ['hurl'],
\ 'description': 'Fix hurl files with hurlfmt.',
\ },
\ 'tidy': {
\ 'function': 'ale#fixers#tidy#Fix',
\ 'suggested_filetypes': ['html'],
@ -127,7 +137,7 @@ let s:default_registry = {
\ },
\ 'eslint': {
\ 'function': 'ale#fixers#eslint#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript'],
\ 'suggested_filetypes': ['javascript', 'typescript', 'astro'],
\ 'description': 'Apply eslint --fix to a file.',
\ },
\ 'mix_format': {
@ -142,7 +152,7 @@ let s:default_registry = {
\ },
\ 'prettier': {
\ 'function': 'ale#fixers#prettier#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'svelte', 'html', 'yaml', 'openapi', 'ruby'],
\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'svelte', 'html', 'yaml', 'openapi', 'ruby', 'astro'],
\ 'description': 'Apply prettier to a file.',
\ },
\ 'prettier_eslint': {
@ -291,6 +301,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['solidity'],
\ 'description': 'Fix Solidity files with forge fmt.',
\ },
\ 'gleam_format': {
\ 'function': 'ale#fixers#gleam_format#Fix',
\ 'suggested_filetypes': ['gleam'],
\ 'description': 'Fix Gleam files with gleam format.',
\ },
\ 'gofmt': {
\ 'function': 'ale#fixers#gofmt#Fix',
\ 'suggested_filetypes': ['go'],
@ -546,6 +561,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['html', 'htmldjango'],
\ 'description': 'Fix HTML files with html-beautify from js-beautify.',
\ },
\ 'htmlbeautifier': {
\ 'function': 'ale#fixers#htmlbeautifier#Fix',
\ 'suggested_filetypes': ['eruby'],
\ 'description': 'Fix ERB files with htmlbeautifier gem.',
\ },
\ 'lua-format': {
\ 'function': 'ale#fixers#lua_format#Fix',
\ 'suggested_filetypes': ['lua'],
@ -641,6 +661,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['nickel'],
\ 'description': 'Fix nickel files with nickel format',
\ },
\ 'rubyfmt': {
\ 'function': 'ale#fixers#rubyfmt#Fix',
\ 'suggested_filetypes': ['ruby'],
\ 'description': 'A formatter for Ruby source code',
\ },
\}
" Reset the function registry to the default entries.

View File

@ -4,22 +4,40 @@
call ale#Set('python_autoflake_executable', 'autoflake')
call ale#Set('python_autoflake_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_autoflake_options', '')
call ale#Set('python_autoflake_auto_pipenv', 0)
call ale#Set('python_autoflake_auto_poetry', 0)
call ale#Set('python_autoflake_auto_uv', 0)
function! ale#fixers#autoflake#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autoflake_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autoflake_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autoflake_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_autoflake', ['autoflake'])
endfunction
function! ale#fixers#autoflake#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_autoflake',
\ ['autoflake'],
\)
let l:executable = ale#fixers#autoflake#GetExecutable(a:buffer)
if !executable(l:executable)
return 0
endif
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run autoflake'
\ : ''
let l:options = ale#Var(a:buffer, 'python_autoflake_options')
return {
\ 'command': ale#Escape(l:executable)
\ 'command': ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --in-place '
\ . ' %t',

View File

@ -4,23 +4,41 @@
call ale#Set('python_autoimport_executable', 'autoimport')
call ale#Set('python_autoimport_options', '')
call ale#Set('python_autoimport_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_autoimport_auto_pipenv', 0)
call ale#Set('python_autoimport_auto_poetry', 0)
call ale#Set('python_autoimport_auto_uv', 0)
function! ale#fixers#autoimport#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autoimport_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autoimport_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autoimport_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_autoimport', ['autoimport'])
endfunction
function! ale#fixers#autoimport#Fix(buffer) abort
let l:executable = ale#fixers#autoimport#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run autoimport'
\ : ''
let l:options = ale#Var(a:buffer, 'python_autoimport_options')
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_autoimport',
\ ['autoimport'],
\)
if !executable(l:executable)
return 0
endif
return {
\ 'cwd': '%s:h',
\ 'command': ale#Escape(l:executable)
\ 'command': ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -',
\}

View File

@ -4,22 +4,40 @@
call ale#Set('python_autopep8_executable', 'autopep8')
call ale#Set('python_autopep8_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_autopep8_options', '')
call ale#Set('python_autopep8_auto_pipenv', 0)
call ale#Set('python_autopep8_auto_poetry', 0)
call ale#Set('python_autopep8_auto_uv', 0)
function! ale#fixers#autopep8#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autopep8_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autopep8_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autopep8_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_autopep8', ['autopep8'])
endfunction
function! ale#fixers#autopep8#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_autopep8',
\ ['autopep8'],
\)
let l:executable = ale#fixers#autopep8#GetExecutable(a:buffer)
if !executable(l:executable)
return 0
endif
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run autopep8'
\ : ''
let l:options = ale#Var(a:buffer, 'python_autopep8_options')
return {
\ 'command': ale#Escape(l:executable)
\ 'command': ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -',
\}

View File

@ -1,17 +1,12 @@
" Author: Akiomi Kamakura <akiomik@gmail.com>
" Description: Fixing files with biome (ex.rome).
function! ale#fixers#biome#Fix(buffer) abort
let l:executable = ale#handlers#biome#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'javascript_biome_options')
let l:node = ale#Var(a:buffer, 'javascript_biome_node_executable')
let l:options = ale#Var(a:buffer, 'biome_options')
let l:apply = ale#Var(a:buffer, 'biome_fixer_apply_unsafe') ? '--apply-unsafe' : '--apply'
return {
\ 'command': (has('win32') ? (ale#Escape(l:node) . ' ') : '')
\ . ale#Escape(l:executable)
\ . ' check --apply'
\ . ale#Pad(l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\ 'command': ale#Escape(l:executable) . ' check ' . l:apply
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t'
\}
endfunction

View File

@ -6,6 +6,7 @@ call ale#Set('python_black_use_global', get(g:, 'ale_use_global_executables', 0)
call ale#Set('python_black_options', '')
call ale#Set('python_black_auto_pipenv', 0)
call ale#Set('python_black_auto_poetry', 0)
call ale#Set('python_black_auto_uv', 0)
call ale#Set('python_black_change_directory', 1)
function! ale#fixers#black#GetExecutable(buffer) abort
@ -19,6 +20,11 @@ function! ale#fixers#black#GetExecutable(buffer) abort
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_black_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_black', ['black'])
endfunction
@ -26,7 +32,7 @@ function! ale#fixers#black#Fix(buffer) abort
let l:executable = ale#fixers#black#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
if l:executable =~? 'pipenv\|poetry\|uv$'
call extend(l:cmd, ['run', 'black'])
endif

View File

@ -0,0 +1,13 @@
" Author: Arash Mousavi <arash-m>
" Description: Support for HTML Beautifier https://github.com/threedaymonk/htmlbeautifier
call ale#Set('eruby_htmlbeautifier_executable', 'htmlbeautifier')
function! ale#fixers#htmlbeautifier#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'eruby_htmlbeautifier_executable')
return {
\ 'command': ale#Escape(l:executable) . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@ -0,0 +1,15 @@
call ale#Set('hurl_hurlfmt_executable', 'hurlfmt')
function! ale#fixers#hurlfmt#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'hurl_hurlfmt_executable')
return ale#Escape(l:executable)
\ . ' --out hurl'
endfunction
function! ale#fixers#hurlfmt#Fix(buffer) abort
return {
\ 'command': ale#fixers#hurlfmt#GetCommand(a:buffer)
\}
endfunction

View File

@ -6,6 +6,7 @@ call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0)
call ale#Set('python_isort_options', '')
call ale#Set('python_isort_auto_pipenv', 0)
call ale#Set('python_isort_auto_poetry', 0)
call ale#Set('python_isort_auto_uv', 0)
function! ale#fixers#isort#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_isort_auto_pipenv'))
@ -18,6 +19,11 @@ function! ale#fixers#isort#GetExecutable(buffer) abort
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_isort_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_isort', ['isort'])
endfunction
@ -25,7 +31,7 @@ function! ale#fixers#isort#GetCmd(buffer) abort
let l:executable = ale#fixers#isort#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
if l:executable =~? 'pipenv\|poetry\|uv$'
call extend(l:cmd, ['run', 'isort'])
endif
@ -36,7 +42,7 @@ function! ale#fixers#isort#FixForVersion(buffer, version) abort
let l:executable = ale#fixers#isort#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
if l:executable =~? 'pipenv\|poetry\|uv$'
call extend(l:cmd, ['run', 'isort'])
endif

View File

@ -4,6 +4,7 @@
call ale#Set('php_cs_fixer_executable', 'php-cs-fixer')
call ale#Set('php_cs_fixer_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('php_cs_fixer_options', '')
call ale#Set('php_cs_fixer_fix_options', '')
function! ale#fixers#php_cs_fixer#GetExecutable(buffer) abort
return ale#path#FindExecutable(a:buffer, 'php_cs_fixer', [
@ -18,7 +19,8 @@ function! ale#fixers#php_cs_fixer#Fix(buffer) abort
return {
\ 'command': ale#Escape(l:executable)
\ . ' ' . ale#Var(a:buffer, 'php_cs_fixer_options')
\ . ' fix %t',
\ . ' fix ' . ale#Var(a:buffer, 'php_cs_fixer_fix_options')
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@ -79,6 +79,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
\ 'openapi': 'yaml',
\ 'html': 'html',
\ 'ruby': 'ruby',
\ 'astro': 'astro',
\}
for l:filetype in l:filetypes

View File

@ -7,6 +7,7 @@ call ale#Set('python_pycln_use_global', get(g:, 'ale_use_global_executables', 0)
call ale#Set('python_pycln_change_directory', 1)
call ale#Set('python_pycln_auto_pipenv', 0)
call ale#Set('python_pycln_auto_poetry', 0)
call ale#Set('python_pycln_auto_uv', 0)
call ale#Set('python_pycln_config_file', '')
function! ale#fixers#pycln#GetCwd(buffer) abort
@ -31,12 +32,17 @@ function! ale#fixers#pycln#GetExecutable(buffer) abort
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pycln_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_pycln', ['pycln'])
endfunction
function! ale#fixers#pycln#GetCommand(buffer) abort
let l:executable = ale#fixers#pycln#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run pycln'
\ : ''
@ -47,7 +53,7 @@ function! ale#fixers#pycln#FixForVersion(buffer, version) abort
let l:executable = ale#fixers#pycln#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
if l:executable =~? 'pipenv\|poetry\|uv$'
call extend(l:cmd, ['run', 'pycln'])
endif

View File

@ -7,6 +7,7 @@ call ale#Set('python_pyflyby_use_global', get(g:, 'ale_use_global_executables',
call ale#Set('python_pyflyby_options', '')
call ale#Set('python_pyflyby_auto_pipenv', 0)
call ale#Set('python_pyflyby_auto_poetry', 0)
call ale#Set('python_pyflyby_auto_uv', 0)
function! ale#fixers#pyflyby#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyflyby_auto_pipenv'))
@ -19,6 +20,11 @@ function! ale#fixers#pyflyby#GetExecutable(buffer) abort
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pyflyby_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_pyflyby', ['tidy-imports'])
endfunction
@ -27,7 +33,7 @@ function! ale#fixers#pyflyby#Fix(buffer) abort
let l:executable = ale#fixers#pyflyby#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
if l:executable =~? 'pipenv\|poetry\|uv$'
call extend(l:cmd, ['run', 'tidy-imports'])
endif

View File

@ -4,22 +4,40 @@
call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports')
call ale#Set('python_reorder_python_imports_options', '')
call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_reorder_python_imports_auto_pipenv', 0)
call ale#Set('python_reorder_python_imports_auto_poetry', 0)
call ale#Set('python_reorder_python_imports_auto_uv', 0)
function! ale#fixers#reorder_python_imports#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_reorder_python_imports_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_reorder_python_imports_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_reorder_python_imports_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_reorder_python_imports', ['reorder-python-imports'])
endfunction
function! ale#fixers#reorder_python_imports#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_reorder_python_imports',
\ ['reorder-python-imports'],
\)
let l:executable = ale#fixers#reorder_python_imports#GetExecutable(a:buffer)
if !executable(l:executable)
return 0
endif
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run reorder-python-imports'
\ : ''
let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options')
return {
\ 'command': ale#Escape(l:executable)
\ 'command': ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\}
endfunction

View File

@ -7,6 +7,7 @@ call ale#Set('python_ruff_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_ruff_change_directory', 1)
call ale#Set('python_ruff_auto_pipenv', 0)
call ale#Set('python_ruff_auto_poetry', 0)
call ale#Set('python_ruff_auto_uv', 0)
function! ale#fixers#ruff#GetCwd(buffer) abort
if ale#Var(a:buffer, 'python_ruff_change_directory')
@ -30,12 +31,17 @@ function! ale#fixers#ruff#GetExecutable(buffer) abort
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_ruff_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_ruff', ['ruff'])
endfunction
function! ale#fixers#ruff#GetCommand(buffer) abort
let l:executable = ale#fixers#ruff#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run ruff'
\ : ''
@ -46,10 +52,15 @@ function! ale#fixers#ruff#FixForVersion(buffer, version) abort
let l:executable = ale#fixers#ruff#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
if l:executable =~? 'pipenv\|poetry\|uv$'
call extend(l:cmd, ['run', 'ruff'])
endif
" NOTE: ruff 0.5.0 removes `ruff <path>` in favor of `ruff check <path>`
if ale#semver#GTE(a:version, [0, 5, 0])
call extend(l:cmd, ['check'])
endif
let l:options = ale#Var(a:buffer, 'python_ruff_options')
if !empty(l:options)

View File

@ -7,6 +7,7 @@ call ale#Set('python_ruff_format_use_global', get(g:, 'ale_use_global_executable
call ale#Set('python_ruff_format_change_directory', 1)
call ale#Set('python_ruff_format_auto_pipenv', 0)
call ale#Set('python_ruff_format_auto_poetry', 0)
call ale#Set('python_ruff_format_auto_uv', 0)
function! ale#fixers#ruff_format#GetCwd(buffer) abort
if ale#Var(a:buffer, 'python_ruff_format_change_directory')
@ -30,12 +31,17 @@ function! ale#fixers#ruff_format#GetExecutable(buffer) abort
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_ruff_format_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_ruff_format', ['ruff'])
endfunction
function! ale#fixers#ruff_format#GetCommand(buffer) abort
let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run ruff'
\ : ''
@ -46,7 +52,7 @@ function! ale#fixers#ruff_format#Fix(buffer) abort
let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
if l:executable =~? 'pipenv\|poetry\|uv$'
call extend(l:cmd, ['run', 'ruff'])
endif

View File

@ -3,17 +3,35 @@
call ale#Set('python_yapf_executable', 'yapf')
call ale#Set('python_yapf_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_yapf_auto_pipenv', 0)
call ale#Set('python_yapf_auto_poetry', 0)
call ale#Set('python_yapf_auto_uv', 0)
function! ale#fixers#yapf#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_yapf_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_yapf_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_yapf_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_yapf', ['yapf'])
endfunction
function! ale#fixers#yapf#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_yapf',
\ ['yapf'],
\)
let l:executable = ale#fixers#yapf#GetExecutable(a:buffer)
if !executable(l:executable)
return 0
endif
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run yapf'
\ : ''
let l:config = ale#path#FindNearestFile(a:buffer, '.style.yapf')
let l:config_options = !empty(l:config)
@ -21,6 +39,6 @@ function! ale#fixers#yapf#Fix(buffer) abort
\ : ''
return {
\ 'command': ale#Escape(l:executable) . l:config_options,
\ 'command': ale#Escape(l:executable) . l:exec_args . l:config_options,
\}
endfunction

View File

@ -1,14 +1,58 @@
" Author: Akiomi Kamakura <akiomik@gmail.com>
" Description: Functions for working with biome, for fixing files.
" Author: Filip Gospodinov <f@gospodinov.ch>
" Description: Functions for working with biome, for checking or fixing files.
call ale#Set('javascript_biome_node_executable', 'node.exe')
call ale#Set('javascript_biome_executable', 'biome')
call ale#Set('javascript_biome_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_biome_options', '')
call ale#Set('biome_executable', 'biome')
call ale#Set('biome_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('biome_options', '')
call ale#Set('biome_fixer_apply_unsafe', 0)
call ale#Set('biome_lsp_project_root', '')
function! ale#handlers#biome#GetExecutable(buffer) abort
return ale#path#FindExecutable(a:buffer, 'javascript_biome', [
return ale#path#FindExecutable(a:buffer, 'biome', [
\ 'node_modules/@biomejs/cli-linux-x64/biome',
\ 'node_modules/@biomejs/cli-linux-arm64/biome',
\ 'node_modules/@biomejs/cli-win32-x64/biome.exe',
\ 'node_modules/@biomejs/cli-win32-arm64/biome.exe',
\ 'node_modules/@biomejs/cli-darwin-x64/biome',
\ 'node_modules/@biomejs/cli-darwin-arm64/biome',
\ 'node_modules/.bin/biome',
\ 'node_modules/@biomejs/biome/bin/biome',
\])
endfunction
function! ale#handlers#biome#GetLanguage(buffer) abort
return getbufvar(a:buffer, '&filetype')
endfunction
function! ale#handlers#biome#GetProjectRoot(buffer) abort
let l:project_root = ale#Var(a:buffer, 'biome_lsp_project_root')
if !empty(l:project_root)
return l:project_root
endif
let l:possible_project_roots = [
\ 'biome.json',
\ 'biome.jsonc',
\ 'package.json',
\ '.git',
\ bufname(a:buffer),
\]
for l:possible_root in l:possible_project_roots
let l:project_root = ale#path#FindNearestFile(a:buffer, l:possible_root)
if empty(l:project_root)
let l:project_root = ale#path#FindNearestDirectory(a:buffer, l:possible_root)
endif
if !empty(l:project_root)
" dir:p expands to /full/path/to/dir/ whereas
" file:p expands to /full/path/to/file (no trailing slash)
" Appending '/' ensures that :h:h removes the path's last segment
" regardless of whether it is a directory or not.
return fnamemodify(l:project_root . '/', ':p:h:h')
endif
endfor
return ''
endfunction

View File

@ -11,12 +11,31 @@ function! ale#handlers#cspell#GetExecutable(buffer) abort
\)
endfunction
function! ale#handlers#cspell#GetLanguageId(buffer) abort
let l:filetype = getbufvar(a:buffer, '&filetype')
if l:filetype is# 'tex'
" Vim's tex corresponds to latex language-id in cspell
return 'latex'
elseif l:filetype is# 'plaintex'
" Vim's plaintex corresponds to tex language-id in cspell
return 'tex'
else
" Fallback to filetype for everything else.
return l:filetype
endif
endfunction
function! ale#handlers#cspell#GetCommand(buffer) abort
let l:executable = ale#handlers#cspell#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'cspell_options')
let l:language_id = ale#handlers#cspell#GetLanguageId(a:buffer)
let l:language_id_option = empty(l:language_id) ? '' : '--language-id="' . l:language_id . '"'
return ale#node#Executable(a:buffer, l:executable)
\ . ' lint --no-color --no-progress --no-summary'
\ . ale#Pad(l:language_id_option)
\ . ale#Pad(l:options)
\ . ' -- stdin'
endfunction

View File

@ -0,0 +1,66 @@
" Author: Adrian Zalewski <aazalewski@hotmail.com>
" Description: Ember-template-lint for checking Handlebars files
function! ale#handlers#embertemplatelint#GetExecutable(buffer) abort
return ale#path#FindExecutable(a:buffer, 'handlebars_embertemplatelint', [
\ 'node_modules/.bin/ember-template-lint',
\])
endfunction
function! ale#handlers#embertemplatelint#GetCommand(buffer, version) abort
if ale#semver#GTE(a:version, [4, 0, 0])
" --json was removed in favor of --format=json in ember-template-lint@4.0.0
return '%e --format=json --filename %s'
endif
return '%e --json --filename %s'
endfunction
function! ale#handlers#embertemplatelint#GetCommandWithVersionCheck(buffer) abort
return ale#semver#RunWithVersionCheck(
\ a:buffer,
\ ale#handlers#embertemplatelint#GetExecutable(a:buffer),
\ '%e --version',
\ function('ale#handlers#embertemplatelint#GetCommand'),
\)
endfunction
function! ale#handlers#embertemplatelint#Handle(buffer, lines) abort
let l:output = []
let l:json = ale#util#FuzzyJSONDecode(a:lines, {})
for l:error in get(values(l:json), 0, [])
if has_key(l:error, 'fatal')
call add(l:output, {
\ 'lnum': get(l:error, 'line', 1),
\ 'col': get(l:error, 'column', 1),
\ 'text': l:error.message,
\ 'type': l:error.severity == 1 ? 'W' : 'E',
\})
else
call add(l:output, {
\ 'lnum': l:error.line,
\ 'col': l:error.column,
\ 'text': l:error.rule . ': ' . l:error.message,
\ 'type': l:error.severity == 1 ? 'W' : 'E',
\})
endif
endfor
return l:output
endfunction
function! ale#handlers#embertemplatelint#DefineLinter(filetype) abort
call ale#Set('handlebars_embertemplatelint_executable', 'ember-template-lint')
call ale#Set('handlebars_embertemplatelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#linter#Define(a:filetype, {
\ 'name': 'embertemplatelint',
\ 'aliases': ['ember-template-lint'],
\ 'executable': function('ale#handlers#embertemplatelint#GetExecutable'),
\ 'command': function('ale#handlers#embertemplatelint#GetCommandWithVersionCheck'),
\ 'callback': 'ale#handlers#embertemplatelint#Handle',
\})
endfunction

View File

@ -18,7 +18,11 @@ call ale#Set('javascript_eslint_suppress_missing_config', 0)
function! ale#handlers#eslint#FindConfig(buffer) abort
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
for l:basename in [
\ 'eslint.config.js',
\ 'eslint.config.mjs',
\ 'eslint.config.cjs',
\ '.eslintrc.js',
\ '.eslintrc.cjs',
\ '.eslintrc.yaml',
\ '.eslintrc.yml',
\ '.eslintrc.json',
@ -41,31 +45,7 @@ endfunction
" Given a buffer, return an appropriate working directory for ESLint.
function! ale#handlers#eslint#GetCwd(buffer) abort
" ESLint 6 loads plugins/configs/parsers from the project root
" By default, the project root is simply the CWD of the running process.
" https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md
" https://github.com/dense-analysis/ale/issues/2787
"
" If eslint is installed in a directory which contains the buffer, assume
" it is the ESLint project root. Otherwise, use nearest node_modules.
" Note: If node_modules not present yet, can't load local deps anyway.
let l:executable = ale#path#FindNearestExecutable(a:buffer, s:executables)
if !empty(l:executable)
let l:modules_index = strridx(l:executable, 'node_modules')
let l:modules_root = l:modules_index > -1 ? l:executable[0:l:modules_index - 2] : ''
let l:sdks_index = strridx(l:executable, ale#path#Simplify('.yarn/sdks'))
let l:sdks_root = l:sdks_index > -1 ? l:executable[0:l:sdks_index - 2] : ''
else
let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules')
let l:modules_root = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : ''
let l:sdks_dir = ale#path#FindNearestDirectory(a:buffer, ale#path#Simplify('.yarn/sdks'))
let l:sdks_root = !empty(l:sdks_dir) ? fnamemodify(l:sdks_dir, ':h:h:h') : ''
endif
return strlen(l:modules_root) > strlen(l:sdks_root) ? l:modules_root : l:sdks_root
return ale#path#Dirname(ale#handlers#eslint#FindConfig(a:buffer))
endfunction
function! ale#handlers#eslint#GetCommand(buffer) abort

View File

@ -49,6 +49,7 @@ function! ale#handlers#shellcheck#GetCommand(buffer, version) abort
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
let l:format = ale#semver#GTE(a:version, [0, 7, 0]) ? 'json1' : 'gcc'
if l:dialect is# 'auto'
let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer)
@ -59,10 +60,69 @@ function! ale#handlers#shellcheck#GetCommand(buffer, version) abort
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
\ . l:external_option
\ . ' -f gcc -'
\ . ' -f ' . l:format . ' -'
endfunction
function! ale#handlers#shellcheck#Handle(buffer, lines) abort
function! s:HandleShellcheckJSON(buffer, lines) abort
try
let l:errors = json_decode(a:lines[0])
catch
return []
endtry
if !has_key(l:errors, 'comments')
return []
endif
let l:output = []
for l:error in l:errors['comments']
if l:error['level'] is# 'error'
let l:type = 'E'
elseif l:error['level'] is# 'info'
let l:type = 'I'
elseif l:error['level'] is# 'style'
let l:type = 'I'
else
let l:type = 'W'
endif
let l:item = {
\ 'lnum': l:error['line'],
\ 'type': l:type,
\ 'text': l:error['message'],
\ 'code': 'SC' . l:error['code'],
\ 'detail': l:error['message'] . "\n\nFor more information:\n https://www.shellcheck.net/wiki/SC" . l:error['code'],
\}
if has_key(l:error, 'column')
let l:item.col = l:error['column']
endif
if has_key(l:error, 'endColumn')
let l:item.end_col = l:error['endColumn'] - 1
endif
if has_key(l:error, 'endLine')
let l:item.end_lnum = l:error['endLine']
endif
" If the filename is something like <stdin>, <nofile> or -, then
" this is an error for the file we checked.
if has_key(l:error, 'file')
if l:error['file'] isnot# '-' && l:error['file'][0] isnot# '<'
let l:item['filename'] = l:error['file']
endif
endif
call add(l:output, l:item)
endfor
return l:output
endfunction
function! s:HandleShellcheckGCC(buffer, lines) abort
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+) \[([^\]]+)\]$'
let l:output = []
@ -80,6 +140,7 @@ function! ale#handlers#shellcheck#Handle(buffer, lines) abort
\ 'type': l:type,
\ 'text': l:match[5],
\ 'code': l:match[6],
\ 'detail': l:match[5] . "\n\nFor more information:\n https://www.shellcheck.net/wiki/" . l:match[6],
\}
if !empty(l:match[3])
@ -98,6 +159,12 @@ function! ale#handlers#shellcheck#Handle(buffer, lines) abort
return l:output
endfunction
function! ale#handlers#shellcheck#Handle(buffer, version, lines) abort
return ale#semver#GTE(a:version, [0, 7, 0])
\ ? s:HandleShellcheckJSON(a:buffer, a:lines)
\ : s:HandleShellcheckGCC(a:buffer, a:lines)
endfunction
function! ale#handlers#shellcheck#DefineLinter(filetype) abort
" This global variable can be set with a string of comma-separated error
" codes to exclude from shellcheck. For example:
@ -118,6 +185,14 @@ function! ale#handlers#shellcheck#DefineLinter(filetype) abort
\ '%e --version',
\ function('ale#handlers#shellcheck#GetCommand'),
\ )},
\ 'callback': 'ale#handlers#shellcheck#Handle',
\ 'callback': {buffer, lines -> ale#semver#RunWithVersionCheck(
\ buffer,
\ ale#Var(buffer, 'sh_shellcheck_executable'),
\ '%e --version',
\ {buffer, version -> ale#handlers#shellcheck#Handle(
\ buffer,
\ l:version,
\ lines)},
\ )},
\})
endfunction

View File

@ -117,10 +117,10 @@ function! ale#hover#ParseLSPResult(contents) abort
for l:line in split(l:item, "\n")
if l:fence_language is v:null
" Look for the start of a code fence. (```python, etc.)
let l:match = matchlist(l:line, '^``` *\([^ ]\+\) *$')
let l:match = matchlist(l:line, '^``` *\([^ ]\+\)\? *$')
if !empty(l:match)
let l:fence_language = l:match[1]
let l:fence_language = len(l:match) > 1 ? l:match[1] : 'text'
if !empty(l:marked_list)
call add(l:fence_lines, '')

View File

@ -40,6 +40,7 @@ let s:default_ale_linter_aliases = {
" NOTE: Update the g:ale_linters documentation when modifying this.
let s:default_ale_linters = {
\ 'apkbuild': ['apkbuild_lint', 'secfixes_check'],
\ 'astro': ['eslint'],
\ 'csh': ['shell'],
\ 'elixir': ['credo', 'dialyxir', 'dogma'],
\ 'go': ['gofmt', 'golangci-lint', 'gopls', 'govet'],
@ -47,9 +48,9 @@ let s:default_ale_linters = {
\ 'hack': ['hack'],
\ 'help': [],
\ 'inko': ['inko'],
\ 'json': ['jsonlint', 'spectral', 'vscodejson'],
\ 'json': ['biome', 'jsonlint', 'spectral', 'vscodejson'],
\ 'json5': [],
\ 'jsonc': [],
\ 'jsonc': ['biome'],
\ 'perl': ['perlcritic'],
\ 'perl6': [],
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'],
@ -60,7 +61,7 @@ let s:default_ale_linters = {
\ 'vue': ['eslint', 'vls'],
\ 'zsh': ['shell'],
\ 'v': ['v'],
\ 'yaml': ['spectral', 'yaml-language-server', 'yamllint'],
\ 'yaml': ['actionlint', 'spectral', 'yaml-language-server', 'yamllint'],
\}
" Testing/debugging helper to unload all linters.

View File

@ -3,6 +3,7 @@
call ale#Set('python_auto_pipenv', '0')
call ale#Set('python_auto_poetry', '0')
call ale#Set('python_auto_uv', '0')
let s:sep = has('win32') ? '\' : '/'
" bin is used for Unix virtualenv directories, and Scripts is for Windows.
@ -43,6 +44,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
\|| filereadable(l:path . '/poetry.lock')
\|| filereadable(l:path . '/pyproject.toml')
\|| filereadable(l:path . '/.tool-versions')
\|| filereadable(l:path . '/uv.lock')
return l:path
endif
endfor
@ -192,3 +194,8 @@ endfunction
function! ale#python#PoetryPresent(buffer) abort
return findfile('poetry.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# ''
endfunction
" Detects whether a poetry environment is present.
function! ale#python#UvPresent(buffer) abort
return findfile('uv.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# ''
endfunction

View File

@ -161,7 +161,7 @@ endfunction
function! s:GroupCmd() abort
if s:supports_sign_groups
return ' group=ale '
return ' group=ale_signs '
else
return ' '
endif
@ -180,13 +180,13 @@ endfunction
function! ale#sign#ParsePattern() abort
if s:supports_sign_groups
" Matches output like :
" line=4 id=1 group=ale name=ALEErrorSign
" строка=1 id=1000001 группа=ale имя=ALEErrorSign
" 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign
" línea=12 id=1000001 grupo=ale nombre=ALEWarningSign
" riga=1 id=1000001 gruppo=ale nome=ALEWarningSign
" Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)'
" line=4 id=1 group=ale_signs name=ALEErrorSign
" строка=1 id=1000001 группа=ale_signs имя=ALEErrorSign
" 行=1 識別子=1000001 グループ=ale_signs 名前=ALEWarningSign
" línea=12 id=1000001 grupo=ale_signs nombre=ALEWarningSign
" riga=1 id=1000001 gruppo=ale_signs nome=ALEWarningSign
" Zeile=235 id=1000001 Gruppe=ale_signs Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale_signs>.*\=(ALE[a-zA-Z]+Sign)'
else
" Matches output like :
" line=4 id=1 name=ALEErrorSign
@ -203,7 +203,7 @@ endfunction
" Given a buffer number, return a List of placed signs [line, id, group]
function! ale#sign#ParseSignsWithGetPlaced(buffer) abort
let l:signs = sign_getplaced(a:buffer, { 'group': s:supports_sign_groups ? 'ale' : '' })[0].signs
let l:signs = sign_getplaced(a:buffer, { 'group': s:supports_sign_groups ? 'ale_signs' : '' })[0].signs
let l:result = []
let l:is_dummy_sign_set = 0
@ -489,7 +489,7 @@ endfunction
" Remove all signs.
function! ale#sign#Clear() abort
if s:supports_sign_groups
sign unplace group=ale *
sign unplace group=ale_signs *
else
sign unplace *
endif