1
0
mirror of https://github.com/amix/vimrc synced 2025-07-12 14:15:00 +08:00

Updated plugins

This commit is contained in:
Amir
2022-08-08 15:45:56 +02:00
parent b41536726f
commit 765adb9da3
216 changed files with 4784 additions and 2112 deletions

View File

@ -16,13 +16,12 @@ endfunction
function! ale#code_action#HandleCodeAction(code_action, options) abort
let l:current_buffer = bufnr('')
let l:changes = a:code_action.changes
let l:should_save = get(a:options, 'should_save')
for l:file_code_edit in l:changes
call ale#code_action#ApplyChanges(
\ l:file_code_edit.fileName,
\ l:file_code_edit.textChanges,
\ l:should_save,
\ a:options,
\)
endfor
endfunction
@ -63,29 +62,29 @@ function! s:ChangeCmp(left, right) abort
return 0
endfunction
function! ale#code_action#ApplyChanges(filename, changes, should_save) abort
let l:current_buffer = bufnr('')
function! ale#code_action#ApplyChanges(filename, changes, options) abort
let l:should_save = get(a:options, 'should_save')
let l:conn_id = get(a:options, 'conn_id')
let l:orig_buffer = bufnr('')
" The buffer is used to determine the fileformat, if available.
let l:buffer = bufnr(a:filename)
let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer
if l:buffer > 0
let l:lines = getbufline(l:buffer, 1, '$')
" Add empty line if there's trailing newline, like readfile() does.
if getbufvar(l:buffer, '&eol')
let l:lines += ['']
endif
else
let l:lines = readfile(a:filename, 'b')
if l:buffer != l:orig_buffer
call ale#util#Execute('silent edit ' . a:filename)
let l:buffer = bufnr('')
endif
if l:is_current_buffer
let l:pos = getpos('.')[1:2]
else
let l:pos = [1, 1]
let l:lines = getbufline(l:buffer, 1, '$')
" Add empty line if there's trailing newline, like readfile() does.
if getbufvar(l:buffer, '&eol')
let l:lines += ['']
endif
let l:pos = getpos('.')[1:2]
" Changes have to be sorted so we apply them from bottom-to-top
for l:code_edit in reverse(sort(copy(a:changes), function('s:ChangeCmp')))
let l:line = l:code_edit.start.line
@ -155,46 +154,25 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort
endif
endfor
if l:buffer > 0
" Make sure ale#util#{Writefile,SetBufferContents} add trailing
" newline if and only if it should be added.
if l:lines[-1] is# '' && getbufvar(l:buffer, '&eol')
call remove(l:lines, -1)
else
call setbufvar(l:buffer, '&eol', 0)
endif
elseif exists('+fixeol') && &fixeol && l:lines[-1] is# ''
" Not in buffer, ale#util#Writefile can't check &eol and always adds
" newline if &fixeol: remove to prevent double trailing newline.
" Make sure to add a trailing newline if and only if it should be added.
if l:lines[-1] is# '' && getbufvar(l:buffer, '&eol')
call remove(l:lines, -1)
endif
if a:should_save || l:buffer < 0
call ale#util#Writefile(l:buffer, l:lines, a:filename)
else
call ale#util#SetBufferContents(l:buffer, l:lines)
call setbufvar(l:buffer, '&eol', 0)
endif
if l:is_current_buffer
if a:should_save
call ale#util#Execute(':e!')
endif
call ale#util#SetBufferContents(l:buffer, l:lines)
call setpos('.', [0, l:pos[0], l:pos[1], 0])
call ale#lsp#NotifyForChanges(l:conn_id, l:buffer)
if l:should_save
call ale#util#Execute('silent w!')
endif
if a:should_save && l:buffer > 0 && !l:is_current_buffer
" Set up a one-time use event that will delete itself to reload the
" buffer next time it's entered to view the changes made to it.
execute 'augroup ALECodeActionReloadGroup' . l:buffer
autocmd!
call setpos('.', [0, l:pos[0], l:pos[1], 0])
execute printf(
\ 'autocmd BufEnter <buffer=%d>'
\ . ' call ale#code_action#ReloadBuffer()',
\ l:buffer
\)
augroup END
if l:orig_buffer != l:buffer && bufexists(l:orig_buffer)
call ale#util#Execute('silent buf ' . string(l:orig_buffer))
endif
endfunction
@ -300,7 +278,7 @@ function! ale#code_action#BuildChangesList(changes_map) abort
endfor
call add(l:changes, {
\ 'fileName': ale#path#FromURI(l:file_name),
\ 'fileName': ale#util#ToResource(l:file_name),
\ 'textChanges': l:text_changes,
\})
endfor

View File

@ -391,8 +391,8 @@ function! s:OnReady(
\ 'character': l:nearest_error.col - 1,
\ },
\ 'end': {
\ 'line': l:nearest_error.end_lnum - 1,
\ 'character': l:nearest_error.end_col,
\ 'line': get(l:nearest_error, 'end_lnum', 1) - 1,
\ 'character': get(l:nearest_error, 'end_col', 0)
\ },
\ },
\ },
@ -457,7 +457,7 @@ function! s:ExecuteGetCodeFix(linter, range, MenuCallback) abort
let [l:end_line, l:end_column] = getpos("'>")[1:2]
endif
let l:column = min([l:column, len(getline(l:line))])
let l:column = max([min([l:column, len(getline(l:line))]), 1])
let l:end_column = min([l:end_column, len(getline(l:end_line))])
let l:Callback = function(

View File

@ -16,7 +16,7 @@ onoremap <silent> <Plug>(ale_show_completion_menu) <Nop>
let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100)
let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', [])
let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50)
let g:ale_completion_autoimport = get(g:, 'ale_completion_autoimport', 0)
let g:ale_completion_autoimport = get(g:, 'ale_completion_autoimport', 1)
let g:ale_completion_tsserver_remove_warnings = get(g:, 'ale_completion_tsserver_remove_warnings', 0)
let s:timer_id = -1
@ -133,11 +133,13 @@ let s:should_complete_map = {
\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
\ 'cpp': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$|-\>$',
\ 'c': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|-\>$',
\}
" Regular expressions for finding the start column to replace with completion.
let s:omni_start_map = {
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
\ 'racket': '\k\+',
\}
" A map of exact characters for triggering LSP completions. Do not forget to
@ -147,6 +149,7 @@ let s:trigger_character_map = {
\ 'typescript': ['.', '''', '"'],
\ 'rust': ['.', '::'],
\ 'cpp': ['.', '::', '->'],
\ 'c': ['.', '->'],
\}
function! s:GetFiletypeValue(map, filetype) abort
@ -581,7 +584,7 @@ function! ale#completion#ParseLSPCompletions(response) abort
continue
endif
if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN
if get(l:item, 'insertTextFormat', s:LSP_INSERT_TEXT_FORMAT_PLAIN) is s:LSP_INSERT_TEXT_FORMAT_PLAIN
\&& type(get(l:item, 'textEdit')) is v:t_dict
let l:text = l:item.textEdit.newText
elseif type(get(l:item, 'insertText')) is v:t_string
@ -776,7 +779,8 @@ function! s:OnReady(linter, lsp_details) abort
if a:linter.lsp is# 'tsserver'
if get(g:, 'ale_completion_tsserver_autoimport') is 1
execute 'echom `g:ale_completion_tsserver_autoimport` is deprecated. Use `g:ale_completion_autoimport` instead.'''
" no-custom-checks
echom '`g:ale_completion_tsserver_autoimport` is deprecated. Use `g:ale_completion_autoimport` instead.'
endif
let l:message = ale#lsp#tsserver_message#Completions(
@ -911,7 +915,8 @@ function! ale#completion#Import() abort
endif
let [l:line, l:column] = getpos('.')[1:2]
let l:column = searchpos('\V' . escape(l:word, '/\'), 'bn', l:line)[1]
let l:column = searchpos('\V' . escape(l:word, '/\'), 'bnc', l:line)[1]
let l:column = l:column + len(l:word) - 1
if l:column isnot 0
let l:started = ale#completion#GetCompletions('ale-import', {

View File

@ -10,12 +10,21 @@ let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s')
let s:cursor_timer = -1
" A wrapper for echon so we can test messages we echo in Vader tests.
function! ale#cursor#Echom(message) abort
" no-custom-checks
exec "norm! :echom a:message\n"
endfunction
function! ale#cursor#TruncatedEcho(original_message) abort
let l:message = a:original_message
" Change tabs to spaces.
let l:message = substitute(l:message, "\t", ' ', 'g')
" Remove any newlines in the message.
let l:message = substitute(l:message, "\n", '', 'g')
" Convert indentation groups into single spaces for better legibility when
" put on a single line
let l:message = substitute(l:message, ' \+', ' ', 'g')
" We need to remember the setting for shortmess and reset it again.
let l:shortmess_options = &l:shortmess
@ -27,7 +36,7 @@ function! ale#cursor#TruncatedEcho(original_message) abort
silent! setlocal shortmess+=T
try
exec "norm! :echomsg l:message\n"
call ale#cursor#Echom(l:message)
catch /^Vim\%((\a\+)\)\=:E523/
" Fallback into manual truncate (#1987)
let l:winwidth = winwidth(0)
@ -87,7 +96,9 @@ function! ale#cursor#EchoCursorWarning(...) abort
elseif get(l:info, 'echoed')
" We'll only clear the echoed message when moving off errors once,
" so we don't continually clear the echo line.
execute 'echo'
"
" no-custom-checks
echo
let l:info.echoed = 0
endif
endif
@ -150,7 +161,8 @@ function! s:ShowCursorDetailForItem(loc, options) abort
" Clear the echo message if we manually displayed details.
if !l:stay_here
execute 'echo'
" no-custom-checks
echo
endif
endif
endfunction

View File

@ -62,7 +62,8 @@ let s:global_variable_list = [
\]
function! s:Echo(message) abort
execute 'echo a:message'
" no-custom-checks
echo a:message
endfunction
function! s:GetLinterVariables(filetype, exclude_linter_names) abort

View File

@ -68,18 +68,27 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
for l:item in l:result
if has_key(l:item, 'targetUri')
" LocationLink items use targetUri
let l:filename = ale#path#FromURI(l:item.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:filename = ale#path#FromURI(l:item.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
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options)
let l:uri_handler = ale#uri#GetURIHandler(l:uri)
if l:uri_handler is# v:null
let l:filename = ale#path#FromFileURI(l:uri)
call ale#util#Open(l:filename, l:line, l:column, l:options)
else
call l:uri_handler.OpenURILink(l:uri, l:line, l:column, l:options, a:conn_id)
endif
break
endfor
endif
@ -112,6 +121,12 @@ function! s:OnReady(line, column, options, capability, linter, lsp_details) abor
\ a:line,
\ a:column
\)
elseif a:capability is# 'implementation'
let l:message = ale#lsp#tsserver_message#Implementation(
\ l:buffer,
\ a:line,
\ a:column
\)
endif
else
" Send a message saying the buffer has changed first, or the
@ -125,6 +140,8 @@ function! s:OnReady(line, column, options, capability, linter, lsp_details) abor
let l:message = ale#lsp#message#Definition(l:buffer, a:line, a:column)
elseif a:capability is# 'typeDefinition'
let l:message = ale#lsp#message#TypeDefinition(l:buffer, a:line, a:column)
elseif a:capability is# 'implementation'
let l:message = ale#lsp#message#Implementation(l:buffer, a:line, a:column)
else
" XXX: log here?
return
@ -166,6 +183,14 @@ function! ale#definition#GoToType(options) abort
endfor
endfunction
function! ale#definition#GoToImpl(options) abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'implementation')
endif
endfor
endfunction
function! ale#definition#GoToCommandHandler(command, ...) abort
let l:options = {}
@ -191,6 +216,8 @@ function! ale#definition#GoToCommandHandler(command, ...) abort
if a:command is# 'type'
call ale#definition#GoToType(l:options)
elseif a:command is# 'implementation'
call ale#definition#GoToImpl(l:options)
else
call ale#definition#GoTo(l:options)
endif

View File

@ -347,6 +347,12 @@ function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist)
if has_key(l:old_item, 'end_lnum')
let l:item.end_lnum = str2nr(l:old_item.end_lnum)
" When the error ends after the end of the file, put it at the
" end. This is only done for the current buffer.
if l:item.bufnr == a:buffer && l:item.end_lnum > l:last_line_number
let l:item.end_lnum = l:last_line_number
endif
endif
if has_key(l:old_item, 'sub_type')

View File

@ -156,4 +156,10 @@ function! ale#events#Init() abort
endif
endif
augroup END
augroup AleURISchemes
autocmd!
autocmd BufNewFile,BufReadPre jdt://** call ale#uri#jdt#ReadJDTLink(expand('<amatch>'))
augroup END
endfunction

View File

@ -77,7 +77,8 @@ function! ale#fix#ApplyFixes(buffer, output) abort
call remove(g:ale_fix_buffer_data, a:buffer)
if !l:data.ignore_file_changed_errors
execute 'echoerr ''The file was changed before fixing finished'''
" no-custom-checks
echoerr 'The file was changed before fixing finished'
endif
return
@ -358,7 +359,8 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort
\ 'There is no fixer named `%s`. Check :ALEFixSuggest',
\ l:function_name,
\)
execute 'echom l:echo_message'
" no-custom-checks
echom l:echo_message
endif
return 0
@ -366,7 +368,8 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort
if empty(l:callback_list)
if a:fixing_flag is# ''
execute 'echom ''No fixers have been defined. Try :ALEFixSuggest'''
" no-custom-checks
echom 'No fixers have been defined. Try :ALEFixSuggest'
endif
return 0

View File

@ -37,6 +37,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.',
\ },
\ 'buf-format': {
\ 'function': 'ale#fixers#buf_format#Fix',
\ 'suggested_filetypes': ['proto'],
\ 'description': 'Fix .proto files with buf format.',
\ },
\ 'buildifier': {
\ 'function': 'ale#fixers#buildifier#Fix',
\ 'suggested_filetypes': ['bzl'],
@ -73,6 +78,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['dhall'],
\ 'description': 'Standard code formatter for the Dhall language and removing dead code',
\ },
\ 'dune': {
\ 'function': 'ale#fixers#dune#Fix',
\ 'suggested_filetypes': ['dune'],
\ 'description': 'Fix dune files with dune format',
\ },
\ 'fecs': {
\ 'function': 'ale#fixers#fecs#Fix',
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
@ -131,6 +141,11 @@ let s:default_registry = {
\ 'description': 'Apply prettier-eslint to a file.',
\ 'aliases': ['prettier-eslint'],
\ },
\ 'pyflyby': {
\ 'function': 'ale#fixers#pyflyby#Fix',
\ 'suggested_filetypes': ['python'],
\ 'description': 'Tidy Python imports with pyflyby.',
\ },
\ 'importjs': {
\ 'function': 'ale#fixers#importjs#Fix',
\ 'suggested_filetypes': ['javascript'],
@ -191,6 +206,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['ruby'],
\ 'description': 'Fix ruby files with standardrb --fix',
\ },
\ 'statix': {
\ 'function': 'ale#fixers#statix#Fix',
\ 'suggested_filetypes': ['nix'],
\ 'description': 'Fix common Nix antipatterns with statix fix',
\ },
\ 'stylelint': {
\ 'function': 'ale#fixers#stylelint#Fix',
\ 'suggested_filetypes': ['css', 'sass', 'scss', 'sugarss', 'stylus'],
@ -216,6 +236,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['php'],
\ 'description': 'Fix PHP files with php-cs-fixer.',
\ },
\ 'pint': {
\ 'function': 'ale#fixers#pint#Fix',
\ 'suggested_filetypes': ['php'],
\ 'description': 'Fix PHP files with Laravel Pint.',
\ },
\ 'astyle': {
\ 'function': 'ale#fixers#astyle#Fix',
\ 'suggested_filetypes': ['c', 'cpp'],
@ -246,6 +271,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['go'],
\ 'description': 'Fix Go files with go fmt.',
\ },
\ 'gofumpt': {
\ 'function': 'ale#fixers#gofumpt#Fix',
\ 'suggested_filetypes': ['go'],
\ 'description': 'Fix Go files with gofumpt, a stricter go fmt.',
\ },
\ 'goimports': {
\ 'function': 'ale#fixers#goimports#Fix',
\ 'suggested_filetypes': ['go'],
@ -421,6 +451,16 @@ let s:default_registry = {
\ 'suggested_filetypes': ['hcl', 'terraform'],
\ 'description': 'Fix tf and hcl files with terraform fmt.',
\ },
\ 'packer': {
\ 'function': 'ale#fixers#packer#Fix',
\ 'suggested_filetypes': ['hcl', 'packer'],
\ 'description': 'Fix Packer HCL files with packer fmt.',
\ },
\ 'crystal': {
\ 'function': 'ale#fixers#crystal#Fix',
\ 'suggested_filetypes': ['cr'],
\ 'description': 'Fix cr (crystal).',
\ },
\ 'ktlint': {
\ 'function': 'ale#fixers#ktlint#Fix',
\ 'suggested_filetypes': ['kt', 'kotlin'],
@ -481,6 +521,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['lua'],
\ 'description': 'Fix Lua files with luafmt.',
\ },
\ 'dprint': {
\ 'function': 'ale#fixers#dprint#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'markdown'],
\ 'description': 'Pluggable and configurable code formatting platform',
\ },
\ 'stylua': {
\ 'function': 'ale#fixers#stylua#Fix',
\ 'suggested_filetypes': ['lua'],
@ -501,10 +546,20 @@ let s:default_registry = {
\ 'suggested_filetypes': ['pascal'],
\ 'description': 'Fix Pascal files with ptop.',
\ },
\ 'opafmt': {
\ 'function': 'ale#fixers#opafmt#Fix',
\ 'suggested_filetypes': ['rego'],
\ 'description': 'Fix rego files with opa fmt.',
\ },
\ 'vfmt': {
\ 'function': 'ale#fixers#vfmt#Fix',
\ 'suggested_filetypes': ['v'],
\ 'description': 'A formatter for V source code.',
\ },
\ 'zigfmt': {
\ 'function': 'ale#fixers#zigfmt#Fix',
\ 'suggested_filetypes': ['zig'],
\ 'description': 'Official formatter for Zig',
\ }
\}

View File

@ -5,27 +5,13 @@ scriptencoding utf-8
call ale#Set('sh_shfmt_executable', 'shfmt')
call ale#Set('sh_shfmt_options', '')
function! s:DefaultOption(buffer) abort
if getbufvar(a:buffer, '&expandtab') == 0
" Tab is used by default
return ''
endif
let l:tabsize = getbufvar(a:buffer, '&shiftwidth')
if l:tabsize == 0
let l:tabsize = getbufvar(a:buffer, '&tabstop')
endif
return ' -i ' . l:tabsize
endfunction
function! ale#fixers#shfmt#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'sh_shfmt_executable')
let l:options = ale#Var(a:buffer, 'sh_shfmt_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (empty(l:options) ? s:DefaultOption(a:buffer) : ' ' . l:options)
\ . ' -filename=%s'
\ . (empty(l:options) ? '' : ' ' . l:options)
\}
endfunction

View File

@ -4,13 +4,30 @@
call ale#Set('c_uncrustify_executable', 'uncrustify')
call ale#Set('c_uncrustify_options', '')
let s:languages = {
\ 'c': 'C',
\ 'cpp': 'CPP',
\ 'cs': 'CS',
\ 'objc': 'OC',
\ 'objcpp': 'OC+',
\ 'd': 'D',
\ 'java': 'JAVA',
\ 'vala': 'VALA',
\ 'p': 'PAWN',
\}
function! ale#fixers#uncrustify#Language(buffer) abort
return get(s:languages, &filetype, 'C')
endfunction
function! ale#fixers#uncrustify#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'c_uncrustify_executable')
let l:options = ale#Var(a:buffer, 'c_uncrustify_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' --no-backup'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' --no-backup '
\ . '-l' . ale#Pad(ale#fixers#uncrustify#Language(a:buffer))
\ . ale#Pad(l:options)
\}
endfunction

View File

@ -7,7 +7,8 @@
function! ale#floating_preview#Show(lines, ...) abort
if !exists('*nvim_open_win') && !has('popupwin')
execute 'echom ''Floating windows not supported in this vim instance.'''
" no-custom-checks
echom 'Floating windows not supported in this vim instance.'
return
endif
@ -105,18 +106,20 @@ function! s:NvimPrepareWindowContent(lines) abort
let l:width += 2
let l:height += 2
let l:hor = g:ale_floating_window_border[0]
let l:top = g:ale_floating_window_border[1]
let l:top_left = g:ale_floating_window_border[2]
let l:top_right = g:ale_floating_window_border[3]
let l:bottom_right = g:ale_floating_window_border[4]
let l:bottom_left = g:ale_floating_window_border[5]
let l:left = get(g:ale_floating_window_border, 0, '|')
let l:top = get(g:ale_floating_window_border, 1, '-')
let l:top_left = get(g:ale_floating_window_border, 2, '+')
let l:top_right = get(g:ale_floating_window_border, 3, '+')
let l:bottom_right = get(g:ale_floating_window_border, 4, '+')
let l:bottom_left = get(g:ale_floating_window_border, 5, '+')
let l:right = get(g:ale_floating_window_border, 6, l:left)
let l:bottom = get(g:ale_floating_window_border, 7, l:top)
let l:lines = [l:top_left . repeat(l:top, l:width - 2) . l:top_right]
for l:line in a:lines
let l:line_width = strchars(l:line)
let l:lines = add(l:lines, l:hor . l:line . repeat(' ', l:width - l:line_width - 2). l:hor)
let l:lines = add(l:lines, l:left . l:line . repeat(' ', l:width - l:line_width - 2). l:right)
endfor
" Truncate the lines
@ -124,7 +127,7 @@ function! s:NvimPrepareWindowContent(lines) abort
let l:lines = l:lines[0:l:max_height]
endif
let l:lines = add(l:lines, l:bottom_left . repeat(l:top, l:width - 2) . l:bottom_right)
let l:lines = add(l:lines, l:bottom_left . repeat(l:bottom, l:width - 2) . l:bottom_right)
return [l:lines, l:width, l:height]
endfunction
@ -157,14 +160,14 @@ function! s:VimCreate(options) abort
\ 'padding': [0, 1, 0, 1],
\ 'border': [],
\ 'borderchars': empty(g:ale_floating_window_border) ? [' '] : [
\ g:ale_floating_window_border[1],
\ g:ale_floating_window_border[0],
\ g:ale_floating_window_border[1],
\ g:ale_floating_window_border[0],
\ g:ale_floating_window_border[2],
\ g:ale_floating_window_border[3],
\ g:ale_floating_window_border[4],
\ g:ale_floating_window_border[5],
\ get(g:ale_floating_window_border, 1, '-'),
\ get(g:ale_floating_window_border, 6, '|'),
\ get(g:ale_floating_window_border, 7, '-'),
\ get(g:ale_floating_window_border, 0, '|'),
\ get(g:ale_floating_window_border, 2, '+'),
\ get(g:ale_floating_window_border, 3, '+'),
\ get(g:ale_floating_window_border, 4, '+'),
\ get(g:ale_floating_window_border, 5, '+'),
\ ],
\ 'moved': 'any',
\ })

View File

@ -11,8 +11,9 @@ endfunction
function! ale#handlers#alex#CreateCommandCallback(flags) abort
return {b -> ale#node#Executable(b, ale#handlers#alex#GetExecutable(b))
\ . ' %s '
\ . a:flags}
\ . ' --stdin '
\ . a:flags
\}
endfunction
function! ale#handlers#alex#Handle(buffer, lines) abort
@ -38,6 +39,7 @@ endfunction
" Define a linter for a specific filetype. Accept flags to adapt to the filetype.
" no flags treat input as markdown
" --html treat input as HTML
" --mdx treat input as MDX
" --text treat input as plaintext
function! ale#handlers#alex#DefineLinter(filetype, flags) abort
call ale#Set('alex_executable', 'alex')
@ -49,6 +51,5 @@ function! ale#handlers#alex#DefineLinter(filetype, flags) abort
\ 'command': ale#handlers#alex#CreateCommandCallback(a:flags),
\ 'output_stream': 'stderr',
\ 'callback': 'ale#handlers#alex#Handle',
\ 'lint_file': 1,
\})
endfunction

View File

@ -19,6 +19,18 @@ function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort
endfunction
function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort
" The compile_commands.json doesn't apply to headers and cppheck will
" bail out if it cannot find a file matching the filter, below. Skip out
" now, for headers. Also, suppress FPs; cppcheck is not meant to
" process lone header files.
let b:buffer_name = bufname(a:buffer)
let b:file_extension = fnamemodify(b:buffer_name, ':e')
if b:file_extension is# 'h' || b:file_extension is# 'hpp'
return ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ . ' --suppress=unusedStructMember'
endif
" If the current buffer is modified, using compile_commands.json does no
" good, so include the file's directory instead. It's not quite as good as
" using --project, but is at least equivalent to running cppcheck on this
@ -35,8 +47,10 @@ function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort
" then use the file to set up import paths, etc.
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
" By default, cppcheck processes every config in compile_commands.json.
" Use --file-filter to limit to just the buffer file.
return !empty(l:json_path)
\ ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ])
\ ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ]) . ' --file-filter=' . ale#Escape(bufname(a:buffer))
\ : ''
endfunction
@ -50,7 +64,12 @@ function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
"test.cpp:974:{column}: error:{inconclusive:inconclusive} Array 'n[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\
" n[3]=3;
" ^
let l:pattern = '\v(\f+):(\d+):(\d+|\{column\}): (\w+):(\{inconclusive:inconclusive\})? ?(.*) \[(\w+)\]\'
"
"" OR if using the misra addon:
"test.c:1:16: style: misra violation (use --rule-texts=<file> to get proper output) [misra-c2012-2.7]\'
"void test( int parm ) {}
" ^
let l:pattern = '\v(\f+):(\d+):(\d+|\{column\}): (\w+):(\{inconclusive:inconclusive\})? ?(.*) \[(%(\w[-.]?)+)\]\'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)

View File

@ -19,6 +19,16 @@ let s:temp_regex_prefix =
\ . substitute(s:temp_dir, '\\', '\\\\', 'g')
\ . '\.\{-}'
function! s:PanicOutput(lines) abort
return [{
\ 'lnum': 1,
\ 'col': 1,
\ 'text': 'ghc panic!',
\ 'type': 'E',
\ 'detail' : join(a:lines, "\n"),
\}]
endfunction
function! ale#handlers#haskell#HandleGHCFormat(buffer, lines) abort
" Look for lines like the following.
"
@ -34,6 +44,14 @@ function! ale#handlers#haskell#HandleGHCFormat(buffer, lines) abort
let l:corrected_lines = []
" If ghc panic error, put the whole message in details and exit.
let l:panic_position = match(a:lines,'ghc: panic!')
let l:panic_end = match(a:lines,'Please report this as a GHC bug:')
if l:panic_position >= 0
return s:PanicOutput(a:lines[l:panic_position : l:panic_end])
endif
" Group the lines into smaller lists.
for l:line in a:lines
if len(matchlist(l:line, l:pattern)) > 0

View File

@ -63,26 +63,35 @@ function! ale#handlers#sml#Handle(buffer, lines) abort
let l:match2 = matchlist(l:line, l:pattern2)
if len(l:match2) != 0
call add(l:out, {
\ 'filename': l:match2[1],
if l:match2[1] =~# 'stdIn$'
let l:loc = {'bufnr': a:buffer}
else
let l:loc = {'filename': l:match2[1]}
endif
call add(l:out, extend(l:loc, {
\ 'lnum': l:match2[2] + 0,
\ 'col' : l:match2[3] - 1,
\ 'text': l:match2[4],
\ 'type': l:match2[4] =~# '^Warning' ? 'W' : 'E',
\})
\}))
continue
endif
let l:match = matchlist(l:line, l:pattern)
if len(l:match) != 0
call add(l:out, {
\ 'filename': l:match[1],
if l:match[1] =~# 'stdIn$'
let l:loc = {'bufnr': a:buffer}
else
let l:loc = {'filename': l:match[1]}
endif
call add(l:out, extend(l:loc, {
\ 'lnum': l:match[2] + 0,
\ 'text': l:match[3] . ': ' . l:match[4],
\ 'type': l:match[3] is# 'error' ? 'E' : 'W',
\})
\}))
continue
endif
endfor

View File

@ -22,6 +22,26 @@ if !hlexists('ALEInfo')
highlight link ALEInfo ALEWarning
endif
if !hlexists('ALEVirtualTextError')
highlight link ALEVirtualTextError ALEError
endif
if !hlexists('ALEVirtualTextStyleError')
highlight link ALEVirtualTextStyleError ALEVirtualTextError
endif
if !hlexists('ALEVirtualTextWarning')
highlight link ALEVirtualTextWarning ALEWarning
endif
if !hlexists('ALEVirtualTextStyleWarning')
highlight link ALEVirtualTextStyleWarning ALEVirtualTextWarning
endif
if !hlexists('ALEVirtualTextInfo')
highlight link ALEVirtualTextInfo ALEVirtualTextWarning
endif
" The maximum number of items for the second argument of matchaddpos()
let s:MAX_POS_VALUES = 8
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)

View File

@ -46,7 +46,7 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort
call balloon_show(a:response.body.displayString)
elseif get(l:options, 'truncated_echo', 0)
if !empty(a:response.body.displayString)
call ale#cursor#TruncatedEcho(split(a:response.body.displayString, "\n")[0])
call ale#cursor#TruncatedEcho(a:response.body.displayString)
endif
elseif g:ale_hover_to_floating_preview || g:ale_floating_preview
call ale#floating_preview#Show(split(a:response.body.displayString, "\n"), {
@ -231,7 +231,11 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort
\&& (l:set_balloons is 1 || l:set_balloons is# 'hover')
call balloon_show(join(l:lines, "\n"))
elseif get(l:options, 'truncated_echo', 0)
call ale#cursor#TruncatedEcho(l:lines[0])
if type(l:lines[0]) is# v:t_list
call ale#cursor#TruncatedEcho(join(l:lines[0], '\n'))
else
call ale#cursor#TruncatedEcho(l:lines[0])
endif
elseif g:ale_hover_to_floating_preview || g:ale_floating_preview
call ale#floating_preview#Show(l:lines, {
\ 'filetype': 'ale-preview.message',

View File

@ -187,10 +187,16 @@ function! ale#job#PrepareCommand(buffer, command) abort
\ : a:command
" If a custom shell is specified, use that.
if exists('g:ale_shell')
let l:shell_arguments = get(g:, 'ale_shell_arguments', &shellcmdflag)
if exists('b:ale_shell')
let l:ale_shell = b:ale_shell
elseif exists('g:ale_shell')
let l:ale_shell = g:ale_shell
endif
return split(g:ale_shell) + split(l:shell_arguments) + [l:command]
if exists('l:ale_shell')
let l:shell_arguments = get(b:, 'ale_shell_arguments', get(g:, 'ale_shell_arguments', &shellcmdflag))
return split(l:ale_shell) + split(l:shell_arguments) + [l:command]
endif
if has('win32')
@ -244,10 +250,16 @@ function! ale#job#Start(command, options) abort
if has_key(a:options, 'out_cb')
let l:job_options.out_cb = function('s:VimOutputCallback')
else
" prevent buffering of output and excessive polling in case close_cb is set
let l:job_options.out_cb = {->0}
endif
if has_key(a:options, 'err_cb')
let l:job_options.err_cb = function('s:VimErrorCallback')
else
" prevent buffering of output and excessive polling in case close_cb is set
let l:job_options.err_cb = {->0}
endif
if has_key(a:options, 'exit_cb')

View File

@ -19,6 +19,7 @@ let s:default_ale_linter_aliases = {
\ 'rmd': 'r',
\ 'systemverilog': 'verilog',
\ 'typescriptreact': ['typescript', 'tsx'],
\ 'vader': ['vim', 'vader'],
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
\ 'vimwiki': 'markdown',
\ 'vue': ['vue', 'javascript'],
@ -45,15 +46,20 @@ let s:default_ale_linters = {
\ 'hack': ['hack'],
\ 'help': [],
\ 'inko': ['inko'],
\ 'json': ['jsonlint', 'spectral', 'vscodejson'],
\ 'json5': [],
\ 'jsonc': [],
\ 'perl': ['perlcritic'],
\ 'perl6': [],
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright'],
\ 'rust': ['cargo', 'rls'],
\ 'spec': [],
\ 'text': [],
\ 'vader': ['vimls'],
\ 'vue': ['eslint', 'vls'],
\ 'zsh': ['shell'],
\ 'v': ['v'],
\ 'yaml': ['spectral', 'yaml-language-server', 'yamllint'],
\}
" Testing/debugging helper to unload all linters.

View File

@ -36,12 +36,22 @@ function! ale#list#IsQuickfixOpen() abort
endfunction
" Check if we should open the list, based on the save event being fired, and
" that setting being on, or the setting just being set to `1`.
function! s:ShouldOpen(buffer) abort
" that setting being on, or that the error count is at least as high as the
" setting when set to an integer value.
function! s:ShouldOpen(buffer, loclist_len) abort
let l:val = ale#Var(a:buffer, 'open_list')
let l:saved = getbufvar(a:buffer, 'ale_save_event_fired', 0)
return l:val is 1 || (l:val is# 'on_save' && l:saved)
return l:val > 0 ? a:loclist_len >= l:val : l:val is# 'on_save' && l:saved
endfunction
" Check if we should close the list, based on the save event being fired, and
" that setting being on, or the setting just being set to an integer value.
function! s:ShouldClose(buffer) abort
let l:val = ale#Var(a:buffer, 'open_list')
let l:saved = getbufvar(a:buffer, 'ale_save_event_fired', 0)
return !((l:val >= 1) || (l:val is# 'on_save' && l:saved))
endfunction
function! s:Deduplicate(list) abort
@ -122,9 +132,9 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
" Open a window to show the problems if we need to.
"
" We'll check if the current buffer's List is not empty here, so the
" window will only be opened if the current buffer has problems.
if s:ShouldOpen(a:buffer) && !empty(a:loclist)
" ShouldOpen() checks if the current buffer has enough problems to be
" opened.
if s:ShouldOpen(a:buffer, len(a:loclist))
let l:winnr = winnr()
let l:mode = mode()
@ -212,8 +222,25 @@ function! ale#list#SetLists(buffer, loclist) abort
endif
endfunction
function! ale#list#ForcePopulateErrorList(populate_quickfix) abort
let l:quickfix_bak = g:ale_set_quickfix
let g:ale_set_quickfix = a:populate_quickfix
let l:loclist_bak = g:ale_set_loclist
let g:ale_set_loclist = !a:populate_quickfix
let l:open_list_bak = g:ale_open_list
let g:ale_open_list = 1
let l:buffer = bufnr('')
let l:loclist = get(g:ale_buffer_info, l:buffer, {'loclist': []}).loclist
call s:SetListsImpl(-1, l:buffer, l:loclist)
let g:ale_open_list = l:open_list_bak
let g:ale_set_loclist = l:loclist_bak
let g:ale_set_quickfix = l:quickfix_bak
endfunction
function! s:CloseWindowIfNeeded(buffer) abort
if ale#Var(a:buffer, 'keep_list_window_open') || !s:ShouldOpen(a:buffer)
if ale#Var(a:buffer, 'keep_list_window_open') || s:ShouldClose(a:buffer)
return
endif

View File

@ -38,11 +38,13 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
\ 'capabilities': {
\ 'hover': 0,
\ 'rename': 0,
\ 'filerename': 0,
\ 'references': 0,
\ 'completion': 0,
\ 'completion_trigger_characters': [],
\ 'definition': 0,
\ 'typeDefinition': 0,
\ 'implementation': 0,
\ 'symbol_search': 0,
\ 'code_actions': 0,
\ 'did_save': 0,
@ -258,6 +260,14 @@ function! s:UpdateCapabilities(conn, capabilities) abort
let a:conn.capabilities.typeDefinition = 1
endif
if get(a:capabilities, 'implementationProvider') is v:true
let a:conn.capabilities.implementation = 1
endif
if type(get(a:capabilities, 'implementationProvider')) is v:t_dict
let a:conn.capabilities.implementation = 1
endif
if get(a:capabilities, 'workspaceSymbolProvider') is v:true
let a:conn.capabilities.symbol_search = 1
endif
@ -378,8 +388,10 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort
let l:conn.capabilities.completion_trigger_characters = ['.']
let l:conn.capabilities.definition = 1
let l:conn.capabilities.typeDefinition = 1
let l:conn.capabilities.implementation = 1
let l:conn.capabilities.symbol_search = 1
let l:conn.capabilities.rename = 1
let l:conn.capabilities.filerename = 1
let l:conn.capabilities.code_actions = 1
endfunction
@ -436,11 +448,20 @@ function! s:SendInitMessage(conn) abort
\ 'typeDefinition': {
\ 'dynamicRegistration': v:false,
\ },
\ 'implementation': {
\ 'dynamicRegistration': v:false,
\ 'linkSupport': v:false,
\ },
\ 'publishDiagnostics': {
\ 'relatedInformation': v:true,
\ },
\ 'codeAction': {
\ 'dynamicRegistration': v:false,
\ 'codeActionLiteralSupport': {
\ 'codeActionKind': {
\ 'valueSet': []
\ }
\ }
\ },
\ 'rename': {
\ 'dynamicRegistration': v:false,
@ -465,6 +486,7 @@ function! ale#lsp#StartProgram(conn_id, executable, command) abort
let l:options = {
\ 'mode': 'raw',
\ 'out_cb': {_, message -> ale#lsp#HandleMessage(a:conn_id, message)},
\ 'exit_cb': { -> ale#lsp#Stop(a:conn_id) },
\}
if has('win32')

View File

@ -35,7 +35,7 @@ function! ale#lsp#message#Initialize(root_path, options, capabilities) abort
\ 'rootPath': a:root_path,
\ 'capabilities': a:capabilities,
\ 'initializationOptions': a:options,
\ 'rootUri': ale#path#ToURI(a:root_path),
\ 'rootUri': ale#util#ToURI(a:root_path),
\}]
endfunction
@ -56,7 +56,7 @@ function! ale#lsp#message#DidOpen(buffer, language_id) abort
return [1, 'textDocument/didOpen', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ 'languageId': a:language_id,
\ 'version': ale#lsp#message#GetNextVersionID(),
\ 'text': join(l:lines, "\n") . "\n",
@ -70,21 +70,21 @@ function! ale#lsp#message#DidChange(buffer) abort
" For changes, we simply send the full text of the document to the server.
return [1, 'textDocument/didChange', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ 'version': ale#lsp#message#GetNextVersionID(),
\ },
\ 'contentChanges': [{'text': join(l:lines, "\n") . "\n"}]
\}]
endfunction
function! ale#lsp#message#DidSave(buffer, includeText) abort
function! ale#lsp#message#DidSave(buffer, include_text) abort
let l:response = [1, 'textDocument/didSave', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\}]
if a:includeText
if a:include_text
let l:response[2].textDocument.version = ale#lsp#message#GetNextVersionID()
let l:response[2].text = ale#util#GetBufferContents(a:buffer)
endif
@ -95,7 +95,7 @@ endfunction
function! ale#lsp#message#DidClose(buffer) abort
return [1, 'textDocument/didClose', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\}]
endfunction
@ -106,7 +106,7 @@ let s:COMPLETION_TRIGGER_CHARACTER = 2
function! ale#lsp#message#Completion(buffer, line, column, trigger_character) abort
let l:message = [0, 'textDocument/completion', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
@ -124,7 +124,7 @@ endfunction
function! ale#lsp#message#Definition(buffer, line, column) abort
return [0, 'textDocument/definition', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
@ -133,7 +133,16 @@ endfunction
function! ale#lsp#message#TypeDefinition(buffer, line, column) abort
return [0, 'textDocument/typeDefinition', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
endfunction
function! ale#lsp#message#Implementation(buffer, line, column) abort
return [0, 'textDocument/implementation', {
\ 'textDocument': {
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
@ -142,7 +151,7 @@ endfunction
function! ale#lsp#message#References(buffer, line, column) abort
return [0, 'textDocument/references', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\ 'context': {'includeDeclaration': v:false},
@ -158,7 +167,7 @@ endfunction
function! ale#lsp#message#Hover(buffer, line, column) abort
return [0, 'textDocument/hover', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
@ -173,7 +182,7 @@ endfunction
function! ale#lsp#message#Rename(buffer, line, column, new_name) abort
return [0, 'textDocument/rename', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\ 'newName': a:new_name,
@ -183,7 +192,7 @@ endfunction
function! ale#lsp#message#CodeAction(buffer, line, column, end_line, end_column, diagnostics) abort
return [0, 'textDocument/codeAction', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'uri': ale#util#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'range': {
\ 'start': {'line': a:line - 1, 'character': a:column - 1},

View File

@ -59,7 +59,7 @@ function! ale#lsp#response#ReadDiagnostics(response) abort
\ && l:diagnostic.relatedInformation isnot v:null
let l:related = deepcopy(l:diagnostic.relatedInformation)
call map(l:related, {key, val ->
\ ale#path#FromURI(val.location.uri) .
\ ale#util#ToResource(val.location.uri) .
\ ':' . (val.location.range.start.line + 1) .
\ ':' . (val.location.range.start.character + 1) .
\ ":\n\t" . val.message

View File

@ -72,6 +72,14 @@ function! ale#lsp#tsserver_message#TypeDefinition(buffer, line, column) abort
\}]
endfunction
function! ale#lsp#tsserver_message#Implementation(buffer, line, column) abort
return [0, 'ts@implementation', {
\ 'line': a:line,
\ 'offset': a:column,
\ 'file': expand('#' . a:buffer . ':p'),
\}]
endfunction
function! ale#lsp#tsserver_message#References(buffer, line, column) abort
return [0, 'ts@references', {
\ 'line': a:line,
@ -101,6 +109,14 @@ function! ale#lsp#tsserver_message#Rename(
\}]
endfunction
function! ale#lsp#tsserver_message#GetEditsForFileRename(
\ oldFilePath, newFilePath) abort
return [0, 'ts@getEditsForFileRename', {
\ 'oldFilePath': a:oldFilePath,
\ 'newFilePath': a:newFilePath,
\}]
endfunction
function! ale#lsp#tsserver_message#OrganizeImports(buffer) abort
return [0, 'ts@organizeImports', {
\ 'scope': {

View File

@ -11,6 +11,22 @@ endif
" A Dictionary to track one-shot handlers for custom LSP requests
let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
" Clear LSP linter data for the linting engine.
function! ale#lsp_linter#ClearLSPData() abort
let s:lsp_linter_map = {}
let s:custom_handlers_map = {}
endfunction
" Only for internal use.
function! ale#lsp_linter#GetLSPLinterMap() abort
return s:lsp_linter_map
endfunction
" Just for tests.
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
let s:lsp_linter_map = a:replacement_map
endfunction
" Check if diagnostics for a particular linter should be ignored.
function! s:ShouldIgnore(buffer, linter_name) abort
" Ignore all diagnostics if LSP integration is disabled.
@ -33,7 +49,7 @@ endfunction
function! s:HandleLSPDiagnostics(conn_id, response) abort
let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:filename = ale#path#FromURI(a:response.params.uri)
let l:filename = ale#util#ToResource(a:response.params.uri)
let l:escaped_name = escape(
\ fnameescape(l:filename),
\ has('win32') ? '^' : '^,}]'
@ -466,8 +482,8 @@ function! s:CheckWithLSP(linter, details) abort
" If this was a file save event, also notify the server of that.
if a:linter.lsp isnot# 'tsserver'
\&& getbufvar(l:buffer, 'ale_save_event_fired', 0)
\&& ale#lsp#HasCapability(l:buffer, 'did_save')
let l:include_text = ale#lsp#HasCapability(l:buffer, 'includeText')
\&& ale#lsp#HasCapability(l:id, 'did_save')
let l:include_text = ale#lsp#HasCapability(l:id, 'includeText')
let l:save_message = ale#lsp#message#DidSave(l:buffer, l:include_text)
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
endif
@ -477,17 +493,6 @@ function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
return ale#lsp_linter#StartLSP(a:buffer, a:linter, function('s:CheckWithLSP'))
endfunction
" Clear LSP linter data for the linting engine.
function! ale#lsp_linter#ClearLSPData() abort
let s:lsp_linter_map = {}
let s:custom_handlers_map = {}
endfunction
" Just for tests.
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
let s:lsp_linter_map = a:replacement_map
endfunction
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:custom_handlers_map, a:response.id)

View File

@ -1,6 +1,6 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Organize imports support for tsserver
"
function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') isnot# 'organizeImports'
return
@ -17,7 +17,10 @@ function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
\ 'description': 'Organize Imports',
\ 'changes': l:file_code_edits,
\ },
\ {}
\ {
\ 'conn_id': a:conn_id,
\ 'should_save': !&hidden,
\ },
\)
endfunction

View File

@ -218,7 +218,7 @@ endfunction
" Convert a filesystem path to a file:// URI
" relatives paths will not be prefixed with the protocol.
" For Windows paths, the `:` in C:\ etc. will not be percent-encoded.
function! ale#path#ToURI(path) abort
function! ale#path#ToFileURI(path) abort
let l:has_drive_letter = a:path[1:2] is# ':\'
return substitute(
@ -231,7 +231,7 @@ function! ale#path#ToURI(path) abort
\)
endfunction
function! ale#path#FromURI(uri) abort
function! ale#path#FromFileURI(uri) abort
if a:uri[:6] is? 'file://'
let l:encoded_path = a:uri[7:]
elseif a:uri[:4] is? 'file:'

View File

@ -26,6 +26,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
\|| filereadable(l:path . '/tox.ini')
\|| filereadable(l:path . '/.pyre_configuration.local')
\|| filereadable(l:path . '/mypy.ini')
\|| filereadable(l:path . '/.mypy.ini')
\|| filereadable(l:path . '/pycodestyle.cfg')
\|| filereadable(l:path . '/.flake8')
\|| filereadable(l:path . '/.flake8rc')

View File

@ -16,6 +16,23 @@ function! ale#references#ClearLSPData() abort
let s:references_map = {}
endfunction
function! ale#references#FormatTSResponseItem(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,
\ 'match': substitute(a:response_item.lineText, '^\s*\(.\{-}\)\s*$', '\1', ''),
\}
endif
endfunction
function! ale#references#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'references'
\&& has_key(s:references_map, a:response.request_seq)
@ -25,23 +42,43 @@ function! ale#references#HandleTSServerResponse(conn_id, response) abort
let l:item_list = []
for l:response_item in a:response.body.refs
call add(l:item_list, {
\ 'filename': l:response_item.file,
\ 'line': l:response_item.start.line,
\ 'column': l:response_item.start.offset,
\ 'match': substitute(l:response_item.lineText, '^\s*\(.\{-}\)\s*$', '\1', ''),
\})
call add(
\ l:item_list,
\ ale#references#FormatTSResponseItem(l:response_item, l:options)
\)
endfor
if empty(l:item_list)
call ale#util#Execute('echom ''No references found.''')
else
call ale#preview#ShowSelection(l:item_list, l:options)
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#preview#ShowSelection(l:item_list, l:options)
endif
endif
endif
endif
endfunction
function! ale#references#FormatLSPResponseItem(response_item, options) abort
if get(a:options, 'open_in') is# 'quickfix'
return {
\ 'filename': ale#util#ToResource(a:response_item.uri),
\ 'lnum': a:response_item.range.start.line + 1,
\ 'col': a:response_item.range.start.character + 1,
\}
else
return {
\ 'filename': ale#util#ToResource(a:response_item.uri),
\ 'line': a:response_item.range.start.line + 1,
\ 'column': a:response_item.range.start.character + 1,
\}
endif
endfunction
function! ale#references#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:references_map, a:response.id)
@ -53,18 +90,22 @@ function! ale#references#HandleLSPResponse(conn_id, response) abort
if type(l:result) is v:t_list
for l:response_item in l:result
call add(l:item_list, {
\ 'filename': ale#path#FromURI(l:response_item.uri),
\ 'line': l:response_item.range.start.line + 1,
\ 'column': l:response_item.range.start.character + 1,
\})
call add(l:item_list,
\ ale#references#FormatLSPResponseItem(l:response_item, l:options)
\)
endfor
endif
if empty(l:item_list)
call ale#util#Execute('echom ''No references found.''')
else
call ale#preview#ShowSelection(l:item_list, l:options)
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#preview#ShowSelection(l:item_list, l:options)
endif
endif
endif
endfunction
@ -119,6 +160,8 @@ function! ale#references#Find(...) abort
let l:options.open_in = 'split'
elseif l:option is? '-vsplit'
let l:options.open_in = 'vsplit'
elseif l:option is? '-quickfix'
let l:options.open_in = 'quickfix'
endif
endfor
endif

View File

@ -84,7 +84,8 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort
\ 'changes': l:changes,
\ },
\ {
\ 'should_save': 1,
\ 'conn_id': a:conn_id,
\ 'should_save': !&hidden,
\ },
\)
endfunction
@ -116,7 +117,8 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
\ 'changes': l:changes,
\ },
\ {
\ 'should_save': 1,
\ 'conn_id': a:conn_id,
\ 'should_save': !&hidden,
\ },
\)
endif

View File

@ -41,7 +41,7 @@ function! ale#symbol#HandleLSPResponse(conn_id, response) abort
let l:location = l:response_item.location
call add(l:item_list, {
\ 'filename': ale#path#FromURI(l:location.uri),
\ 'filename': ale#util#ToResource(l:location.uri),
\ 'line': l:location.range.start.line + 1,
\ 'column': l:location.range.start.character + 1,
\ 'match': l:response_item.name,

View File

@ -62,25 +62,34 @@ function! ale#test#SetFilename(path) abort
silent! noautocmd execute 'file ' . fnameescape(l:full_path)
endfunction
function! s:RemoveModule(results) abort
function! RemoveNewerKeys(results) abort
for l:item in a:results
if has_key(l:item, 'module')
call remove(l:item, 'module')
endif
if has_key(l:item, 'end_col')
call remove(l:item, 'end_col')
endif
if has_key(l:item, 'end_lnum')
call remove(l:item, 'end_lnum')
endif
endfor
endfunction
" Return loclist data without the module string, only in newer Vim versions.
function! ale#test#GetLoclistWithoutModule() abort
" Return loclist data with only the keys supported by the lowest Vim versions.
function! ale#test#GetLoclistWithoutNewerKeys() abort
let l:results = getloclist(0)
call s:RemoveModule(l:results)
call RemoveNewerKeys(l:results)
return l:results
endfunction
function! ale#test#GetQflistWithoutModule() abort
" Return quickfix data with only the keys supported by the lowest Vim versions.
function! ale#test#GetQflistWithoutNewerKeys() abort
let l:results = getqflist()
call s:RemoveModule(l:results)
call RemoveNewerKeys(l:results)
return l:results
endfunction

View File

@ -64,7 +64,8 @@ function! ale#toggle#ToggleBuffer(buffer) abort
" Disabling ALE globally removes autocmd events, so we cannot enable
" linting locally when linting is disabled globally
if l:enabled && !g:ale_enabled
execute 'echom ''ALE cannot be enabled locally when disabled globally'''
" no-custom-checks
echom 'ALE cannot be enabled locally when disabled globally'
return
endif

View File

@ -25,3 +25,19 @@ function! ale#uri#Decode(value) abort
\ 'g'
\)
endfunction
let s:uri_handlers = {
\ 'jdt': {
\ 'OpenURILink': function('ale#uri#jdt#OpenJDTLink'),
\ }
\}
function! ale#uri#GetURIHandler(uri) abort
for l:scheme in keys(s:uri_handlers)
if a:uri =~# '^'.l:scheme.'://'
return s:uri_handlers[scheme]
endif
endfor
return v:null
endfunction

View File

@ -25,7 +25,8 @@ function! ale#util#ShowMessage(string, ...) abort
" We have to assume the user is using a monospace font.
if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns)
execute 'echo a:string'
" no-custom-checks
echo a:string
else
call ale#preview#Show(split(a:string, "\n"), extend(
\ {
@ -491,8 +492,12 @@ function! ale#util#FindItemAtCursor(buffer) abort
return [l:info, l:loc]
endfunction
function! ale#util#Input(message, value) abort
return input(a:message, a:value)
function! ale#util#Input(message, value, ...) abort
if a:0 > 0
return input(a:message, a:value, a:1)
else
return input(a:message, a:value)
endif
endfunction
function! ale#util#HasBuflineApi() abort
@ -539,3 +544,31 @@ endfunction
function! ale#util#GetBufferContents(buffer) abort
return join(getbufline(a:buffer, 1, '$'), '\n') . '\n'
endfunction
function! ale#util#ToURI(resource) abort
let l:uri_handler = ale#uri#GetURIHandler(a:resource)
if l:uri_handler is# v:null
" resource is a filesystem path
let l:uri = ale#path#ToFileURI(a:resource)
else
" resource is a URI
let l:uri = a:resource
endif
return l:uri
endfunction
function! ale#util#ToResource(uri) abort
let l:uri_handler = ale#uri#GetURIHandler(a:uri)
if l:uri_handler is# v:null
" resource is a filesystem path
let l:resource = ale#path#FromFileURI(a:uri)
else
" resource is a URI
let l:resource = a:uri
endif
return l:resource
endfunction

View File

@ -18,26 +18,6 @@ elseif has('textprop') && has('popupwin')
let s:has_virt_text = 1
endif
if !hlexists('ALEVirtualTextError')
highlight link ALEVirtualTextError ALEError
endif
if !hlexists('ALEVirtualTextStyleError')
highlight link ALEVirtualTextStyleError ALEVirtualTextError
endif
if !hlexists('ALEVirtualTextWarning')
highlight link ALEVirtualTextWarning ALEWarning
endif
if !hlexists('ALEVirtualTextStyleWarning')
highlight link ALEVirtualTextStyleWarning ALEVirtualTextWarning
endif
if !hlexists('ALEVirtualTextInfo')
highlight link ALEVirtualTextInfo ALEVirtualTextWarning
endif
function! ale#virtualtext#Clear() abort
if !s:has_virt_text
return