mirror of
https://github.com/amix/vimrc
synced 2025-06-16 01:25:00 +08:00
Updated plugins
This commit is contained in:
@ -2,6 +2,11 @@
|
||||
" Description: Primary code path for the plugin
|
||||
" Manages execution of linters when requested by autocommands
|
||||
|
||||
" Strings used for severity in the echoed message
|
||||
let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
||||
let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
|
||||
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
||||
|
||||
let s:lint_timer = -1
|
||||
let s:queued_buffer_number = -1
|
||||
let s:should_lint_file_for_buffer = {}
|
||||
@ -32,8 +37,8 @@ function! ale#CallWithCooldown(timestamp_key, func, arglist) abort
|
||||
endfunction
|
||||
|
||||
" Return 1 if a file is too large for ALE to handle.
|
||||
function! ale#FileTooLarge() abort
|
||||
let l:max = ale#Var(bufnr(''), 'maximum_file_size')
|
||||
function! ale#FileTooLarge(buffer) abort
|
||||
let l:max = getbufvar(a:buffer, 'ale_maximum_file_size', get(g:, 'ale_maximum_file_size', 0))
|
||||
|
||||
return l:max > 0 ? (line2byte(line('$') + 1) > l:max) : 0
|
||||
endfunction
|
||||
@ -46,39 +51,47 @@ function! ale#ShouldDoNothing(buffer) abort
|
||||
" The checks are split into separate if statements to make it possible to
|
||||
" profile each check individually with Vim's profiling tools.
|
||||
|
||||
" Do nothing if ALE is disabled.
|
||||
if !getbufvar(a:buffer, 'ale_enabled', get(g:, 'ale_enabled', 0))
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Don't perform any checks when newer NeoVim versions are exiting.
|
||||
if get(v:, 'exiting', v:null) isnot v:null
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing for blacklisted files
|
||||
if index(g:ale_filetype_blacklist, getbufvar(a:buffer, '&filetype')) >= 0
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
|
||||
" Do nothing when there's no filetype.
|
||||
if l:filetype is# ''
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if running from command mode
|
||||
" Do nothing for blacklisted files.
|
||||
if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if running from command mode.
|
||||
if s:getcmdwintype_exists && !empty(getcmdwintype())
|
||||
return 1
|
||||
endif
|
||||
|
||||
let l:filename = fnamemodify(bufname(a:buffer), ':t')
|
||||
|
||||
" Do nothing for directories.
|
||||
if l:filename is# '.'
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if running in the sandbox
|
||||
" Do nothing if running in the sandbox.
|
||||
if ale#util#InSandbox()
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if ALE is disabled.
|
||||
if !ale#Var(a:buffer, 'enabled')
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if the file is too large.
|
||||
if ale#FileTooLarge()
|
||||
if ale#FileTooLarge(a:buffer)
|
||||
return 1
|
||||
endif
|
||||
|
||||
|
77
sources_non_forked/ale/autoload/ale/autocmd.vim
Normal file
77
sources_non_forked/ale/autoload/ale/autocmd.vim
Normal file
@ -0,0 +1,77 @@
|
||||
function! ale#autocmd#InitAuGroups() abort
|
||||
" This value used to be a Boolean as a Number, and is now a String.
|
||||
let l:text_changed = '' . g:ale_lint_on_text_changed
|
||||
|
||||
augroup ALEPatternOptionsGroup
|
||||
autocmd!
|
||||
autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand('<abuf>')))
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnTextChangedGroup
|
||||
autocmd!
|
||||
if g:ale_enabled
|
||||
if l:text_changed is? 'always' || l:text_changed is# '1'
|
||||
autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||
elseif l:text_changed is? 'normal'
|
||||
autocmd TextChanged * call ale#Queue(g:ale_lint_delay)
|
||||
elseif l:text_changed is? 'insert'
|
||||
autocmd TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||
endif
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnEnterGroup
|
||||
autocmd!
|
||||
if g:ale_enabled
|
||||
" Handle everything that needs to happen when buffers are entered.
|
||||
autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
if g:ale_enabled && g:ale_lint_on_enter
|
||||
autocmd BufWinEnter,BufRead * call ale#Queue(0, 'lint_file', str2nr(expand('<abuf>')))
|
||||
" Track when the file is changed outside of Vim.
|
||||
autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnFiletypeChangeGroup
|
||||
autocmd!
|
||||
if g:ale_enabled && g:ale_lint_on_filetype_changed
|
||||
" Only start linting if the FileType actually changes after
|
||||
" opening a buffer. The FileType will fire when buffers are opened.
|
||||
autocmd FileType * call ale#events#FileTypeEvent(
|
||||
\ str2nr(expand('<abuf>')),
|
||||
\ expand('<amatch>')
|
||||
\)
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnSaveGroup
|
||||
autocmd!
|
||||
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnInsertLeave
|
||||
autocmd!
|
||||
if g:ale_enabled && g:ale_lint_on_insert_leave
|
||||
autocmd InsertLeave * call ale#Queue(0)
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALECursorGroup
|
||||
autocmd!
|
||||
if g:ale_enabled && g:ale_echo_cursor
|
||||
autocmd CursorMoved,CursorHold * call ale#cursor#EchoCursorWarningWithDelay()
|
||||
" Look for a warning to echo as soon as we leave Insert mode.
|
||||
" The script's position variable used when moving the cursor will
|
||||
" not be changed here.
|
||||
autocmd InsertLeave * call ale#cursor#EchoCursorWarning()
|
||||
endif
|
||||
augroup END
|
||||
|
||||
if !g:ale_enabled
|
||||
augroup! ALERunOnTextChangedGroup
|
||||
augroup! ALERunOnEnterGroup
|
||||
augroup! ALERunOnInsertLeave
|
||||
augroup! ALECursorGroup
|
||||
endif
|
||||
endfunction
|
@ -12,7 +12,21 @@ function! ale#balloon#MessageForPos(bufnr, lnum, col) abort
|
||||
let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist
|
||||
let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col)
|
||||
|
||||
return l:index >= 0 ? l:loclist[l:index].text : ''
|
||||
" Show the diagnostics message if found, 'Hover' output otherwise
|
||||
if l:index >= 0
|
||||
return l:loclist[l:index].text
|
||||
elseif exists('*balloon_show') || getbufvar(
|
||||
\ a:bufnr,
|
||||
\ 'ale_set_balloons_legacy_echo',
|
||||
\ get(g:, 'ale_set_balloons_legacy_echo', 0)
|
||||
\)
|
||||
" Request LSP/tsserver hover information, but only if this version of
|
||||
" Vim supports the balloon_show function, or if we turned a legacy
|
||||
" setting on.
|
||||
call ale#hover#Show(a:bufnr, a:lnum, a:col, {'called_from_balloonexpr': 1})
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#balloon#Expr() abort
|
||||
@ -20,9 +34,22 @@ function! ale#balloon#Expr() abort
|
||||
endfunction
|
||||
|
||||
function! ale#balloon#Disable() abort
|
||||
set noballooneval balloonexpr=
|
||||
set noballooneval noballoonevalterm
|
||||
set balloonexpr=
|
||||
endfunction
|
||||
|
||||
function! ale#balloon#Enable() abort
|
||||
set ballooneval balloonexpr=ale#balloon#Expr()
|
||||
if !has('balloon_eval') && !has('balloon_eval_term')
|
||||
return
|
||||
endif
|
||||
|
||||
if has('balloon_eval')
|
||||
set ballooneval
|
||||
endif
|
||||
|
||||
if has('balloon_eval_term')
|
||||
set balloonevalterm
|
||||
endif
|
||||
|
||||
set balloonexpr=ale#balloon#Expr()
|
||||
endfunction
|
||||
|
@ -1,6 +1,10 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Completion support for LSP linters
|
||||
|
||||
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 s:timer_id = -1
|
||||
let s:last_done_pos = []
|
||||
|
||||
@ -28,6 +32,8 @@ let s:LSP_COMPLETION_REFERENCE_KIND = 18
|
||||
" the insert cursor is. If one of these matches, we'll check for completions.
|
||||
let s:should_complete_map = {
|
||||
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$',
|
||||
\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
|
||||
\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
|
||||
\}
|
||||
|
||||
" Regular expressions for finding the start column to replace with completion.
|
||||
@ -38,6 +44,8 @@ let s:omni_start_map = {
|
||||
" A map of exact characters for triggering LSP completions.
|
||||
let s:trigger_character_map = {
|
||||
\ '<default>': ['.'],
|
||||
\ 'typescript': ['.', '''', '"'],
|
||||
\ 'rust': ['.', '::'],
|
||||
\}
|
||||
|
||||
function! s:GetFiletypeValue(map, filetype) abort
|
||||
@ -74,33 +82,49 @@ function! ale#completion#GetTriggerCharacter(filetype, prefix) abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Filter(suggestions, prefix) abort
|
||||
function! ale#completion#Filter(buffer, suggestions, prefix) abort
|
||||
let l:excluded_words = ale#Var(a:buffer, 'completion_excluded_words')
|
||||
|
||||
" For completing...
|
||||
" foo.
|
||||
" ^
|
||||
" We need to include all of the given suggestions.
|
||||
if a:prefix is# '.'
|
||||
return a:suggestions
|
||||
let l:filtered_suggestions = a:suggestions
|
||||
else
|
||||
let l:filtered_suggestions = []
|
||||
|
||||
" Filter suggestions down to those starting with the prefix we used for
|
||||
" finding suggestions in the first place.
|
||||
"
|
||||
" Some completion tools will include suggestions which don't even start
|
||||
" with the characters we have already typed.
|
||||
for l:item in a:suggestions
|
||||
" A List of String values or a List of completion item Dictionaries
|
||||
" is accepted here.
|
||||
let l:word = type(l:item) == type('') ? l:item : l:item.word
|
||||
|
||||
" Add suggestions if the suggestion starts with a case-insensitive
|
||||
" match for the prefix.
|
||||
if l:word[: len(a:prefix) - 1] is? a:prefix
|
||||
call add(l:filtered_suggestions, l:item)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
let l:filtered_suggestions = []
|
||||
|
||||
" Filter suggestions down to those starting with the prefix we used for
|
||||
" finding suggestions in the first place.
|
||||
"
|
||||
" Some completion tools will include suggestions which don't even start
|
||||
" with the characters we have already typed.
|
||||
for l:item in a:suggestions
|
||||
" A List of String values or a List of completion item Dictionaries
|
||||
" is accepted here.
|
||||
let l:word = type(l:item) == type('') ? l:item : l:item.word
|
||||
|
||||
" Add suggestions if the suggestion starts with a case-insensitive
|
||||
" match for the prefix.
|
||||
if l:word[: len(a:prefix) - 1] is? a:prefix
|
||||
call add(l:filtered_suggestions, l:item)
|
||||
if !empty(l:excluded_words)
|
||||
" Copy the List if needed. We don't want to modify the argument.
|
||||
" We shouldn't make a copy if we don't need to.
|
||||
if l:filtered_suggestions is a:suggestions
|
||||
let l:filtered_suggestions = copy(a:suggestions)
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Remove suggestions with words in the exclusion List.
|
||||
call filter(
|
||||
\ l:filtered_suggestions,
|
||||
\ 'index(l:excluded_words, type(v:val) is type('''') ? v:val : v:val.word) < 0',
|
||||
\)
|
||||
endif
|
||||
|
||||
return l:filtered_suggestions
|
||||
endfunction
|
||||
@ -178,7 +202,9 @@ function! ale#completion#ParseTSServerCompletions(response) abort
|
||||
endfunction
|
||||
|
||||
function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:results = []
|
||||
let l:names_with_details = []
|
||||
|
||||
for l:suggestion in a:response.body
|
||||
let l:displayParts = []
|
||||
@ -212,10 +238,44 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
\})
|
||||
endfor
|
||||
|
||||
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
|
||||
|
||||
if !empty(l:names) && len(l:names) != len(l:results)
|
||||
let l:names_with_details = map(copy(l:results), 'v:val.word')
|
||||
let l:missing_names = filter(
|
||||
\ copy(l:names),
|
||||
\ 'index(l:names_with_details, v:val) < 0',
|
||||
\)
|
||||
|
||||
for l:name in l:missing_names
|
||||
call add(l:results, {
|
||||
\ 'word': l:name,
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'menu': '',
|
||||
\ 'info': '',
|
||||
\})
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:results
|
||||
endfunction
|
||||
|
||||
function! ale#completion#NullFilter(buffer, item) abort
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! ale#completion#ParseLSPCompletions(response) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:info = get(b:, 'ale_completion_info', {})
|
||||
let l:Filter = get(l:info, 'completion_filter', v:null)
|
||||
|
||||
if l:Filter is v:null
|
||||
let l:Filter = function('ale#completion#NullFilter')
|
||||
else
|
||||
let l:Filter = ale#util#GetFunction(l:Filter)
|
||||
endif
|
||||
|
||||
let l:item_list = []
|
||||
|
||||
if type(get(a:response, 'result')) is type([])
|
||||
@ -228,6 +288,16 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
||||
let l:results = []
|
||||
|
||||
for l:item in l:item_list
|
||||
if !call(l:Filter, [l:buffer, l:item])
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:word = matchstr(l:item.label, '\v^[^(]+')
|
||||
|
||||
if empty(l:word)
|
||||
continue
|
||||
endif
|
||||
|
||||
" See :help complete-items for Vim completion kinds
|
||||
if l:item.kind is s:LSP_COMPLETION_METHOD_KIND
|
||||
let l:kind = 'm'
|
||||
@ -244,14 +314,18 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
||||
endif
|
||||
|
||||
call add(l:results, {
|
||||
\ 'word': l:item.label,
|
||||
\ 'word': l:word,
|
||||
\ 'kind': l:kind,
|
||||
\ 'icase': 1,
|
||||
\ 'menu': l:item.detail,
|
||||
\ 'info': l:item.documentation,
|
||||
\ 'menu': get(l:item, 'detail', ''),
|
||||
\ 'info': get(l:item, 'documentation', ''),
|
||||
\})
|
||||
endfor
|
||||
|
||||
if has_key(l:info, 'prefix')
|
||||
return ale#completion#Filter(l:buffer, l:results, l:info.prefix)
|
||||
endif
|
||||
|
||||
return l:results
|
||||
endfunction
|
||||
|
||||
@ -264,19 +338,25 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let l:command = get(a:response, 'command', '')
|
||||
|
||||
if l:command is# 'completions'
|
||||
let l:names = ale#completion#Filter(
|
||||
\ l:buffer,
|
||||
\ ale#completion#ParseTSServerCompletions(a:response),
|
||||
\ b:ale_completion_info.prefix,
|
||||
\)[: g:ale_completion_max_suggestions - 1]
|
||||
|
||||
" We need to remember some names for tsserver, as it doesn't send
|
||||
" details back for everything we send.
|
||||
call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names)
|
||||
|
||||
if !empty(l:names)
|
||||
let b:ale_completion_info.request_id = ale#lsp#Send(
|
||||
\ b:ale_completion_info.conn_id,
|
||||
\ ale#lsp#tsserver_message#CompletionEntryDetails(
|
||||
\ bufnr(''),
|
||||
\ l:buffer,
|
||||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ l:names,
|
||||
@ -349,6 +429,10 @@ function! s:GetLSPCompletions(linter) abort
|
||||
if l:request_id
|
||||
let b:ale_completion_info.conn_id = l:id
|
||||
let b:ale_completion_info.request_id = l:request_id
|
||||
|
||||
if has_key(a:linter, 'completion_filter')
|
||||
let b:ale_completion_info.completion_filter = a:linter.completion_filter
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -378,10 +462,7 @@ function! ale#completion#GetCompletions() abort
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
if l:linter.lsp is# 'tsserver'
|
||||
\|| get(g:, 'ale_completion_experimental_lsp_support', 0)
|
||||
call s:GetLSPCompletions(l:linter)
|
||||
endif
|
||||
call s:GetLSPCompletions(l:linter)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
@ -0,0 +1,3 @@
|
||||
function! ale#completion#python#CompletionItemFilter(buffer, item) abort
|
||||
return a:item.label !~# '\v^__[a-z_]+__'
|
||||
endfunction
|
@ -1,6 +1,11 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Echoes lint message for the current line, if any
|
||||
|
||||
" Controls the milliseconds delay before echoing a message.
|
||||
let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10)
|
||||
" A string format for the echoed message.
|
||||
let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s')
|
||||
|
||||
let s:cursor_timer = -1
|
||||
let s:last_pos = [0, 0, 0]
|
||||
|
||||
|
@ -51,6 +51,7 @@ let s:global_variable_list = [
|
||||
\ 'ale_sign_warning',
|
||||
\ 'ale_statusline_format',
|
||||
\ 'ale_type_map',
|
||||
\ 'ale_use_global_executables',
|
||||
\ 'ale_warn_about_trailing_blank_lines',
|
||||
\ 'ale_warn_about_trailing_whitespace',
|
||||
\]
|
||||
@ -167,6 +168,30 @@ function! s:EchoLinterAliases(all_linters) abort
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:EchoLSPErrorMessages(all_linter_names) abort
|
||||
let l:lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
|
||||
let l:header_echoed = 0
|
||||
|
||||
for l:linter_name in a:all_linter_names
|
||||
let l:error_list = get(l:lsp_error_messages, l:linter_name, [])
|
||||
|
||||
if !empty(l:error_list)
|
||||
if !l:header_echoed
|
||||
call s:Echo(' LSP Error Messages:')
|
||||
call s:Echo('')
|
||||
endif
|
||||
|
||||
call s:Echo('(Errors for ' . l:linter_name . ')')
|
||||
|
||||
for l:message in l:error_list
|
||||
for l:line in split(l:message, "\n")
|
||||
call s:Echo(l:line)
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#Info() abort
|
||||
let l:filetype = &filetype
|
||||
|
||||
@ -199,6 +224,7 @@ function! ale#debugging#Info() abort
|
||||
call s:Echo(' Global Variables:')
|
||||
call s:Echo('')
|
||||
call s:EchoGlobalVariables()
|
||||
call s:EchoLSPErrorMessages(l:all_names)
|
||||
call s:Echo(' Command History:')
|
||||
call s:Echo('')
|
||||
call s:EchoCommandHistory()
|
||||
@ -211,3 +237,14 @@ function! ale#debugging#InfoToClipboard() abort
|
||||
|
||||
call s:Echo('ALEInfo copied to your clipboard')
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToFile(filename) abort
|
||||
let l:expanded_filename = expand(a:filename)
|
||||
|
||||
redir => l:output
|
||||
silent call ale#debugging#Info()
|
||||
redir END
|
||||
|
||||
call writefile(split(l:output, "\n"), l:expanded_filename)
|
||||
call s:Echo('ALEInfo written to ' . l:expanded_filename)
|
||||
endfunction
|
||||
|
@ -13,37 +13,21 @@ function! ale#definition#SetMap(map) abort
|
||||
let s:go_to_definition_map = a:map
|
||||
endfunction
|
||||
|
||||
" This function is used so we can check the execution of commands without
|
||||
" running them.
|
||||
function! ale#definition#Execute(expr) abort
|
||||
execute a:expr
|
||||
endfunction
|
||||
|
||||
function! ale#definition#ClearLSPData() abort
|
||||
let s:go_to_definition_map = {}
|
||||
endfunction
|
||||
|
||||
function! ale#definition#Open(options, filename, line, column) abort
|
||||
if a:options.open_in_tab
|
||||
call ale#definition#Execute('tabedit ' . fnameescape(a:filename))
|
||||
else
|
||||
call ale#definition#Execute('edit ' . fnameescape(a:filename))
|
||||
endif
|
||||
|
||||
call cursor(a:line, a:column)
|
||||
endfunction
|
||||
|
||||
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') is# 'definition'
|
||||
\&& 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
|
||||
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
|
||||
|
||||
call ale#definition#Open(l:options, l:filename, l:line, l:column)
|
||||
call ale#util#Open(l:filename, l:line, l:column, l:options)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
@ -67,7 +51,7 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
|
||||
let l:line = l:item.range.start.line + 1
|
||||
let l:column = l:item.range.start.character
|
||||
|
||||
call ale#definition#Open(l:options, l:filename, l:line, l:column)
|
||||
call ale#util#Open(l:filename, l:line, l:column, l:options)
|
||||
break
|
||||
endfor
|
||||
endif
|
||||
|
@ -2,6 +2,9 @@
|
||||
" Description: Backend execution and job management
|
||||
" Executes linters in the background, using NeoVim or Vim 8 jobs
|
||||
|
||||
" Remapping of linter problems.
|
||||
let g:ale_type_map = get(g:, 'ale_type_map', {})
|
||||
|
||||
" Stores information for each job including:
|
||||
"
|
||||
" linter: The linter dictionary for the job.
|
||||
@ -44,7 +47,7 @@ function! ale#engine#IsExecutable(buffer, executable) abort
|
||||
|
||||
" Cache the executable check if we found it, or if the option to cache
|
||||
" failing checks is on.
|
||||
if l:result || g:ale_cache_executable_check_failures
|
||||
if l:result || get(g:, 'ale_cache_executable_check_failures', 0)
|
||||
let s:executable_cache_map[a:executable] = l:result
|
||||
endif
|
||||
|
||||
@ -81,6 +84,11 @@ function! ale#engine#ClearLSPData() abort
|
||||
let s:lsp_linter_map = {}
|
||||
endfunction
|
||||
|
||||
" Just for tests.
|
||||
function! ale#engine#SetLSPLinterMap(replacement_map) abort
|
||||
let s:lsp_linter_map = a:replacement_map
|
||||
endfunction
|
||||
|
||||
" This function is documented and part of the public API.
|
||||
"
|
||||
" Return 1 if ALE is busy checking a given buffer
|
||||
@ -93,11 +101,13 @@ endfunction
|
||||
" Register a temporary file to be managed with the ALE engine for
|
||||
" a current job run.
|
||||
function! ale#engine#ManageFile(buffer, filename) abort
|
||||
call ale#engine#InitBufferInfo(a:buffer)
|
||||
call add(g:ale_buffer_info[a:buffer].temporary_file_list, a:filename)
|
||||
endfunction
|
||||
|
||||
" Same as the above, but manage an entire directory.
|
||||
function! ale#engine#ManageDirectory(buffer, directory) abort
|
||||
call ale#engine#InitBufferInfo(a:buffer)
|
||||
call add(g:ale_buffer_info[a:buffer].temporary_directory_list, a:directory)
|
||||
endfunction
|
||||
|
||||
@ -270,20 +280,38 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
call ale#engine#HandleLoclist('tsserver', l:buffer, l:loclist)
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPErrorMessage(error_message) abort
|
||||
execute 'echoerr ''Error from LSP:'''
|
||||
function! s:HandleLSPErrorMessage(linter_name, response) abort
|
||||
if !g:ale_history_enabled || !g:ale_history_log_output
|
||||
return
|
||||
endif
|
||||
|
||||
for l:line in split(a:error_message, "\n")
|
||||
execute 'echoerr l:line'
|
||||
endfor
|
||||
if empty(a:linter_name)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:message = ale#lsp#response#GetErrorMessage(a:response)
|
||||
|
||||
if empty(l:message)
|
||||
return
|
||||
endif
|
||||
|
||||
" This global variable is set here so we don't load the debugging.vim file
|
||||
" until someone uses :ALEInfo.
|
||||
let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
|
||||
|
||||
if !has_key(g:ale_lsp_error_messages, a:linter_name)
|
||||
let g:ale_lsp_error_messages[a:linter_name] = []
|
||||
endif
|
||||
|
||||
call add(g:ale_lsp_error_messages[a:linter_name], l:message)
|
||||
endfunction
|
||||
|
||||
function! ale#engine#HandleLSPResponse(conn_id, response) abort
|
||||
let l:method = get(a:response, 'method', '')
|
||||
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
|
||||
|
||||
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
|
||||
" Uncomment this line to print LSP error messages.
|
||||
" call s:HandleLSPErrorMessage(a:response.error.message)
|
||||
call s:HandleLSPErrorMessage(l:linter_name, a:response)
|
||||
elseif l:method is# 'textDocument/publishDiagnostics'
|
||||
call s:HandleLSPDiagnostics(a:conn_id, a:response)
|
||||
elseif get(a:response, 'type', '') is# 'event'
|
||||
@ -339,6 +367,7 @@ function! ale#engine#SetResults(buffer, loclist) abort
|
||||
|
||||
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
||||
silent doautocmd <nomodeline> User ALELintPost
|
||||
" remove in 2.0
|
||||
" Old DEPRECATED name; call it for backwards compatibility.
|
||||
silent doautocmd <nomodeline> User ALELint
|
||||
endif
|
||||
@ -393,7 +422,7 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
|
||||
\ 'text': l:old_item.text,
|
||||
\ 'lnum': str2nr(l:old_item.lnum),
|
||||
\ 'col': str2nr(get(l:old_item, 'col', 0)),
|
||||
\ 'vcol': get(l:old_item, 'vcol', 0),
|
||||
\ 'vcol': 0,
|
||||
\ 'type': get(l:old_item, 'type', 'E'),
|
||||
\ 'nr': get(l:old_item, 'nr', -1),
|
||||
\ 'linter_name': a:linter_name,
|
||||
@ -453,6 +482,20 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
|
||||
" When errors go beyond the end of the file, put them at the end.
|
||||
" This is only done for the current buffer.
|
||||
let l:item.lnum = l:last_line_number
|
||||
elseif get(l:old_item, 'vcol', 0)
|
||||
" Convert virtual column positions to byte positions.
|
||||
" The positions will be off if the buffer has changed recently.
|
||||
let l:line = getbufline(a:buffer, l:item.lnum)[0]
|
||||
|
||||
let l:item.col = ale#util#Col(l:line, l:item.col)
|
||||
|
||||
if has_key(l:item, 'end_col')
|
||||
let l:end_line = get(l:item, 'end_lnum', l:line) != l:line
|
||||
\ ? getbufline(a:buffer, l:item.end_lnum)[0]
|
||||
\ : l:line
|
||||
|
||||
let l:item.end_col = ale#util#Col(l:end_line, l:item.end_col)
|
||||
endif
|
||||
endif
|
||||
|
||||
call add(l:new_loclist, l:item)
|
||||
@ -572,6 +615,8 @@ function! s:RunJob(options) abort
|
||||
\ 'output': [],
|
||||
\ 'next_chain_index': l:next_chain_index,
|
||||
\}
|
||||
|
||||
silent doautocmd <nomodeline> User ALEJobStarted
|
||||
endif
|
||||
|
||||
if g:ale_history_enabled
|
||||
|
@ -19,7 +19,7 @@ function! ale#events#SaveEvent(buffer) abort
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'fix_on_save')
|
||||
let l:will_fix = ale#fix#Fix('save_file')
|
||||
let l:will_fix = ale#fix#Fix(a:buffer, 'save_file')
|
||||
let l:should_lint = l:should_lint && !l:will_fix
|
||||
endif
|
||||
|
||||
|
@ -28,8 +28,6 @@ function! ale#fix#ApplyQueuedFixes() abort
|
||||
call remove(g:ale_fix_buffer_data, l:buffer)
|
||||
|
||||
if l:data.changes_made
|
||||
call setline(1, l:data.output)
|
||||
|
||||
let l:start_line = len(l:data.output) + 1
|
||||
let l:end_line = len(l:data.lines_before)
|
||||
|
||||
@ -39,6 +37,8 @@ function! ale#fix#ApplyQueuedFixes() abort
|
||||
call winrestview(l:save)
|
||||
endif
|
||||
|
||||
call setline(1, l:data.output)
|
||||
|
||||
if l:data.should_save
|
||||
if empty(&buftype)
|
||||
noautocmd :w!
|
||||
@ -356,14 +356,16 @@ function! s:RunFixer(options) abort
|
||||
call ale#fix#ApplyFixes(l:buffer, l:input)
|
||||
endfunction
|
||||
|
||||
function! s:GetCallbacks() abort
|
||||
if type(get(b:, 'ale_fixers')) is type([])
|
||||
function! s:GetCallbacks(buffer, linters) abort
|
||||
if len(a:linters)
|
||||
let l:callback_list = a:linters
|
||||
elseif type(get(b:, 'ale_fixers')) is type([])
|
||||
" Lists can be used for buffer-local variables only
|
||||
let l:callback_list = b:ale_fixers
|
||||
else
|
||||
" buffer and global options can use dictionaries mapping filetypes to
|
||||
" callbacks to run.
|
||||
let l:fixers = ale#Var(bufnr(''), 'fixers')
|
||||
let l:fixers = ale#Var(a:buffer, 'fixers')
|
||||
let l:callback_list = []
|
||||
|
||||
for l:sub_type in split(&filetype, '\.')
|
||||
@ -422,19 +424,13 @@ endfunction
|
||||
" Accepts an optional argument for what to do when fixing.
|
||||
"
|
||||
" Returns 0 if no fixes can be applied, and 1 if fixing can be done.
|
||||
function! ale#fix#Fix(...) abort
|
||||
if len(a:0) > 1
|
||||
throw 'too many arguments!'
|
||||
endif
|
||||
|
||||
let l:fixing_flag = get(a:000, 0, '')
|
||||
|
||||
if l:fixing_flag isnot# '' && l:fixing_flag isnot# 'save_file'
|
||||
function! ale#fix#Fix(buffer, fixing_flag, ...) abort
|
||||
if a:fixing_flag isnot# '' && a:fixing_flag isnot# 'save_file'
|
||||
throw "fixing_flag must be either '' or 'save_file'"
|
||||
endif
|
||||
|
||||
try
|
||||
let l:callback_list = s:GetCallbacks()
|
||||
let l:callback_list = s:GetCallbacks(a:buffer, a:000)
|
||||
catch /E700\|BADNAME/
|
||||
let l:function_name = join(split(split(v:exception, ':')[3]))
|
||||
let l:echo_message = printf(
|
||||
@ -447,29 +443,27 @@ function! ale#fix#Fix(...) abort
|
||||
endtry
|
||||
|
||||
if empty(l:callback_list)
|
||||
if l:fixing_flag is# ''
|
||||
if a:fixing_flag is# ''
|
||||
execute 'echom ''No fixers have been defined. Try :ALEFixSuggest'''
|
||||
endif
|
||||
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
for l:job_id in keys(s:job_info_map)
|
||||
call remove(s:job_info_map, l:job_id)
|
||||
call ale#job#Stop(l:job_id)
|
||||
endfor
|
||||
|
||||
" Clean up any files we might have left behind from a previous run.
|
||||
call ale#fix#RemoveManagedFiles(l:buffer)
|
||||
call ale#fix#InitBufferData(l:buffer, l:fixing_flag)
|
||||
call ale#fix#RemoveManagedFiles(a:buffer)
|
||||
call ale#fix#InitBufferData(a:buffer, a:fixing_flag)
|
||||
|
||||
silent doautocmd <nomodeline> User ALEFixPre
|
||||
|
||||
call s:RunFixer({
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'input': g:ale_fix_buffer_data[l:buffer].lines_before,
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'input': g:ale_fix_buffer_data[a:buffer].lines_before,
|
||||
\ 'callback_index': 0,
|
||||
\ 'callback_list': l:callback_list,
|
||||
\})
|
||||
|
@ -17,6 +17,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix PEP8 issues with autopep8.',
|
||||
\ },
|
||||
\ 'black': {
|
||||
\ 'function': 'ale#fixers#black#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix PEP8 issues with black.',
|
||||
\ },
|
||||
\ 'prettier_standard': {
|
||||
\ 'function': 'ale#fixers#prettier_standard#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
@ -90,6 +95,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'Fix ruby files with rufo',
|
||||
\ },
|
||||
\ 'scalafmt': {
|
||||
\ 'function': 'ale#fixers#scalafmt#Fix',
|
||||
\ 'suggested_filetypes': ['scala'],
|
||||
\ 'description': 'Fix Scala files using scalafmt',
|
||||
\ },
|
||||
\ 'standard': {
|
||||
\ 'function': 'ale#fixers#standard#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
@ -180,6 +190,21 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['json'],
|
||||
\ 'description': 'Fix JSON files with jq.',
|
||||
\ },
|
||||
\ 'perltidy': {
|
||||
\ 'function': 'ale#fixers#perltidy#Fix',
|
||||
\ 'suggested_filetypes': ['perl'],
|
||||
\ 'description': 'Fix Perl files with perltidy.',
|
||||
\ },
|
||||
\ 'xo': {
|
||||
\ 'function': 'ale#fixers#xo#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
\ 'description': 'Fix JavaScript files using xo --fix.',
|
||||
\ },
|
||||
\ 'qmlfmt': {
|
||||
\ 'function': 'ale#fixers#qmlfmt#Fix',
|
||||
\ 'suggested_filetypes': ['qml'],
|
||||
\ 'description': 'Fix QML files with qmlfmt.',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
@ -272,6 +297,14 @@ function! s:ShouldSuggestForType(suggested_filetypes, type_list) abort
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:IsGenericFixer(suggested_filetypes) abort
|
||||
if empty(a:suggested_filetypes)
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:FormatEntry(key, entry) abort
|
||||
let l:aliases_str = ''
|
||||
|
||||
@ -291,6 +324,27 @@ function! s:FormatEntry(key, entry) abort
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Get list of applicable fixers for filetype, including generic fixers
|
||||
function! ale#fix#registry#GetApplicableFixers(filetype) abort
|
||||
let l:type_list = split(a:filetype, '\.')
|
||||
let l:fixer_name_list = []
|
||||
|
||||
for l:key in sort(keys(s:entries))
|
||||
let l:suggested_filetypes = s:entries[l:key].suggested_filetypes
|
||||
|
||||
if s:IsGenericFixer(l:suggested_filetypes) || s:ShouldSuggestForType(l:suggested_filetypes, l:type_list)
|
||||
call add(l:fixer_name_list, l:key)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:fixer_name_list
|
||||
endfunction
|
||||
|
||||
" Function that returns autocomplete candidates for ALEFix command
|
||||
function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort
|
||||
return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead')
|
||||
endfunction
|
||||
|
||||
" Suggest functions to use from the registry.
|
||||
function! ale#fix#registry#Suggest(filetype) abort
|
||||
let l:type_list = split(a:filetype, '\.')
|
||||
@ -310,7 +364,7 @@ function! ale#fix#registry#Suggest(filetype) abort
|
||||
let l:generic_fixer_list = []
|
||||
|
||||
for l:key in sort(keys(s:entries))
|
||||
if empty(s:entries[l:key].suggested_filetypes)
|
||||
if s:IsGenericFixer(s:entries[l:key].suggested_filetypes)
|
||||
call add(
|
||||
\ l:generic_fixer_list,
|
||||
\ s:FormatEntry(l:key, s:entries[l:key]),
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Description: Fixing files with autopep8.
|
||||
|
||||
call ale#Set('python_autopep8_executable', 'autopep8')
|
||||
call ale#Set('python_autopep8_use_global', 0)
|
||||
call ale#Set('python_autopep8_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_autopep8_options', '')
|
||||
|
||||
function! ale#fixers#autopep8#Fix(buffer) abort
|
||||
|
26
sources_non_forked/ale/autoload/ale/fixers/black.vim
Normal file
26
sources_non_forked/ale/autoload/ale/fixers/black.vim
Normal file
@ -0,0 +1,26 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Fixing Python files with black.
|
||||
"
|
||||
call ale#Set('python_black_executable', 'black')
|
||||
call ale#Set('python_black_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_black_options', '')
|
||||
|
||||
function! ale#fixers#black#Fix(buffer) abort
|
||||
let l:executable = ale#python#FindExecutable(
|
||||
\ a:buffer,
|
||||
\ 'python_black',
|
||||
\ ['black'],
|
||||
\)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_black_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -',
|
||||
\}
|
||||
endfunction
|
@ -1,4 +1,4 @@
|
||||
" Author: eborden <evan@evan-borden.com>
|
||||
" Author: eborden <evan@evan-borden.com>, ifyouseewendy <ifyouseewendy@gmail.com>, aspidiets <emarshall85@gmail.com>
|
||||
" Description: Integration of brittany with ALE.
|
||||
|
||||
call ale#Set('haskell_brittany_executable', 'brittany')
|
||||
@ -8,6 +8,7 @@ function! ale#fixers#brittany#Fix(buffer) abort
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' --write-mode inplace'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
|
@ -3,7 +3,7 @@ scriptencoding utf-8
|
||||
" Description: Fixing C/C++ files with clang-format.
|
||||
|
||||
call ale#Set('c_clangformat_executable', 'clang-format')
|
||||
call ale#Set('c_clangformat_use_global', 0)
|
||||
call ale#Set('c_clangformat_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('c_clangformat_options', '')
|
||||
|
||||
function! ale#fixers#clangformat#GetExecutable(buffer) abort
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Description: Integration of elm-format with ALE.
|
||||
|
||||
call ale#Set('elm_format_executable', 'elm-format')
|
||||
call ale#Set('elm_format_use_global', 0)
|
||||
call ale#Set('elm_format_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('elm_format_options', '--yes')
|
||||
|
||||
function! ale#fixers#elm_format#GetExecutable(buffer) abort
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
call ale#Set('json_fixjson_executable', 'fixjson')
|
||||
call ale#Set('json_fixjson_options', '')
|
||||
call ale#Set('json_fixjson_use_global', 0)
|
||||
call ale#Set('json_fixjson_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#fixers#fixjson#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'json_fixjson', [
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Description: Integration of Google-java-format with ALE.
|
||||
|
||||
call ale#Set('google_java_format_executable', 'google-java-format')
|
||||
call ale#Set('google_java_format_use_global', 0)
|
||||
call ale#Set('google_java_format_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('google_java_format_options', '')
|
||||
|
||||
function! ale#fixers#google_java_format#Fix(buffer) abort
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Description: Fixing Python imports with isort.
|
||||
|
||||
call ale#Set('python_isort_executable', 'isort')
|
||||
call ale#Set('python_isort_use_global', 0)
|
||||
call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#fixers#isort#Fix(buffer) abort
|
||||
let l:executable = ale#python#FindExecutable(
|
||||
|
18
sources_non_forked/ale/autoload/ale/fixers/perltidy.vim
Normal file
18
sources_non_forked/ale/autoload/ale/fixers/perltidy.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Author: kfly8 <kentafly88@gmail.com>
|
||||
" Description: Integration of perltidy with ALE.
|
||||
|
||||
call ale#Set('perl_perltidy_executable', 'perltidy')
|
||||
call ale#Set('perl_perltidy_options', '')
|
||||
|
||||
function! ale#fixers#perltidy#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'perl_perltidy_executable')
|
||||
let l:options = ale#Var(a:buffer, 'perl_perltidy_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -b'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
@ -2,7 +2,8 @@
|
||||
" Description: Fixing files with php-cs-fixer.
|
||||
|
||||
call ale#Set('php_cs_fixer_executable', 'php-cs-fixer')
|
||||
call ale#Set('php_cs_fixer_use_global', 0)
|
||||
call ale#Set('php_cs_fixer_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('php_cs_fixer_options', '')
|
||||
|
||||
function! ale#fixers#php_cs_fixer#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'php_cs_fixer', [
|
||||
@ -14,10 +15,9 @@ endfunction
|
||||
function! ale#fixers#php_cs_fixer#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#php_cs_fixer#GetExecutable(a:buffer)
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' fix %t',
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' ' . ale#Var(a:buffer, 'php_cs_fixer_options')
|
||||
\ . ' fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
call ale#Set('php_phpcbf_standard', '')
|
||||
call ale#Set('php_phpcbf_executable', 'phpcbf')
|
||||
call ale#Set('php_phpcbf_use_global', 0)
|
||||
call ale#Set('php_phpcbf_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#fixers#phpcbf#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'php_phpcbf', [
|
||||
|
@ -3,7 +3,7 @@
|
||||
" Description: Integration of Prettier with ALE.
|
||||
|
||||
call ale#Set('javascript_prettier_executable', 'prettier')
|
||||
call ale#Set('javascript_prettier_use_global', 0)
|
||||
call ale#Set('javascript_prettier_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_prettier_options', '')
|
||||
|
||||
function! ale#fixers#prettier#GetExecutable(buffer) abort
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
function! ale#fixers#prettier_eslint#SetOptionDefaults() abort
|
||||
call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint')
|
||||
call ale#Set('javascript_prettier_eslint_use_global', 0)
|
||||
call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_prettier_eslint_options', '')
|
||||
endfunction
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Description: Integration of Prettier Standard with ALE.
|
||||
|
||||
call ale#Set('javascript_prettier_standard_executable', 'prettier-standard')
|
||||
call ale#Set('javascript_prettier_standard_use_global', 0)
|
||||
call ale#Set('javascript_prettier_standard_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_prettier_standard_options', '')
|
||||
|
||||
function! ale#fixers#prettier_standard#GetExecutable(buffer) abort
|
||||
|
11
sources_non_forked/ale/autoload/ale/fixers/qmlfmt.vim
Normal file
11
sources_non_forked/ale/autoload/ale/fixers/qmlfmt.vim
Normal file
@ -0,0 +1,11 @@
|
||||
call ale#Set('qml_qmlfmt_executable', 'qmlfmt')
|
||||
|
||||
function! ale#fixers#qmlfmt#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'qml_qmlfmt_executable')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#qmlfmt#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#Escape(ale#fixers#qmlfmt#GetExecutable(a:buffer)),
|
||||
\}
|
||||
endfunction
|
26
sources_non_forked/ale/autoload/ale/fixers/scalafmt.vim
Normal file
26
sources_non_forked/ale/autoload/ale/fixers/scalafmt.vim
Normal file
@ -0,0 +1,26 @@
|
||||
" Author: Jeffrey Lau https://github.com/zoonfafer
|
||||
" Description: Integration of Scalafmt with ALE.
|
||||
|
||||
call ale#Set('scala_scalafmt_executable', 'scalafmt')
|
||||
call ale#Set('scala_scalafmt_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('scala_scalafmt_options', '')
|
||||
|
||||
function! ale#fixers#scalafmt#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'scala_scalafmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'scala_scalafmt_options')
|
||||
let l:exec_args = l:executable =~? 'ng$'
|
||||
\ ? ' scalafmt'
|
||||
\ : ''
|
||||
|
||||
return ale#Escape(l:executable) . l:exec_args
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t'
|
||||
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#scalafmt#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#fixers#scalafmt#GetCommand(a:buffer),
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
@ -2,7 +2,7 @@
|
||||
" Description: Fixing files with Standard.
|
||||
|
||||
call ale#Set('javascript_standard_executable', 'standard')
|
||||
call ale#Set('javascript_standard_use_global', 0)
|
||||
call ale#Set('javascript_standard_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_standard_options', '')
|
||||
|
||||
function! ale#fixers#standard#GetExecutable(buffer) abort
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Description: Fixing files with stylelint.
|
||||
|
||||
call ale#Set('stylelint_executable', 'stylelint')
|
||||
call ale#Set('stylelint_use_global', 0)
|
||||
call ale#Set('stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#fixers#stylelint#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'stylelint', [
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Description: Integration of SwiftFormat with ALE.
|
||||
|
||||
call ale#Set('swift_swiftformat_executable', 'swiftformat')
|
||||
call ale#Set('swift_swiftformat_use_global', 0)
|
||||
call ale#Set('swift_swiftformat_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('swift_swiftformat_options', '')
|
||||
|
||||
function! ale#fixers#swiftformat#GetExecutable(buffer) abort
|
||||
|
23
sources_non_forked/ale/autoload/ale/fixers/xo.vim
Normal file
23
sources_non_forked/ale/autoload/ale/fixers/xo.vim
Normal file
@ -0,0 +1,23 @@
|
||||
" Author: Albert Marquez - https://github.com/a-marquez
|
||||
" Description: Fixing files with XO.
|
||||
|
||||
call ale#Set('javascript_xo_executable', 'xo')
|
||||
call ale#Set('javascript_xo_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_xo_options', '')
|
||||
|
||||
function! ale#fixers#xo#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'javascript_xo', [
|
||||
\ 'node_modules/xo/cli.js',
|
||||
\ 'node_modules/.bin/xo',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#xo#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#xo#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
@ -2,7 +2,7 @@
|
||||
" Description: Fixing Python files with yapf.
|
||||
|
||||
call ale#Set('python_yapf_executable', 'yapf')
|
||||
call ale#Set('python_yapf_use_global', 0)
|
||||
call ale#Set('python_yapf_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#fixers#yapf#Fix(buffer) abort
|
||||
let l:executable = ale#python#FindExecutable(
|
||||
|
@ -5,7 +5,7 @@ let s:sep = has('win32') ? '\' : '/'
|
||||
|
||||
call ale#Set('javascript_eslint_options', '')
|
||||
call ale#Set('javascript_eslint_executable', 'eslint')
|
||||
call ale#Set('javascript_eslint_use_global', 0)
|
||||
call ale#Set('javascript_eslint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_eslint_suppress_eslintignore', 0)
|
||||
call ale#Set('javascript_eslint_suppress_missing_config', 0)
|
||||
|
||||
|
@ -48,7 +48,7 @@ function! ale#handlers#gcc#HandleGCCFormat(buffer, lines) abort
|
||||
|
||||
let l:item = {
|
||||
\ 'lnum': str2nr(l:match[2]),
|
||||
\ 'type': l:match[4] is# 'error' ? 'E' : 'W',
|
||||
\ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W',
|
||||
\ 'text': s:RemoveUnicodeQuotes(l:match[5]),
|
||||
\}
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
" Author: KabbAmine - https://github.com/KabbAmine,
|
||||
" Ben Falconer <ben@falconers.me.uk>
|
||||
|
||||
function! ale#handlers#sasslint#GetCommand(buffer) abort
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#Escape('sass-lint')
|
||||
\ . ' -v -q -f compact %t'
|
||||
endfunction
|
37
sources_non_forked/ale/autoload/ale/handlers/scala.vim
Normal file
37
sources_non_forked/ale/autoload/ale/handlers/scala.vim
Normal file
@ -0,0 +1,37 @@
|
||||
" Author: Nils Leuzinger - https://github.com/PawkyPenguin
|
||||
" Description: Scala linting handlers for scalac-like compilers.
|
||||
|
||||
function! ale#handlers#scala#HandleScalacLintFormat(buffer, lines) abort
|
||||
" Matches patterns line the following:
|
||||
"
|
||||
" /var/folders/5q/20rgxx3x1s34g3m14n5bq0x80000gn/T/vv6pSsy/0:26: error: expected class or object definition
|
||||
let l:pattern = '^.\+:\(\d\+\): \(\w\+\): \(.\+\)'
|
||||
let l:output = []
|
||||
let l:ln = 0
|
||||
|
||||
for l:line in a:lines
|
||||
let l:ln = l:ln + 1
|
||||
let l:match = matchlist(l:line, l:pattern)
|
||||
|
||||
if len(l:match) == 0
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:text = l:match[3]
|
||||
let l:type = l:match[2] is# 'error' ? 'E' : 'W'
|
||||
let l:col = 0
|
||||
|
||||
if l:ln + 1 < len(a:lines)
|
||||
let l:col = stridx(a:lines[l:ln + 1], '^')
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:col + 1,
|
||||
\ 'text': l:text,
|
||||
\ 'type': l:type,
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
@ -2,7 +2,7 @@
|
||||
" Description: textlint, a proofreading tool (https://textlint.github.io/)
|
||||
|
||||
call ale#Set('textlint_executable', 'textlint')
|
||||
call ale#Set('textlint_use_global', 0)
|
||||
call ale#Set('textlint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('textlint_options', '')
|
||||
|
||||
function! ale#handlers#textlint#GetExecutable(buffer) abort
|
||||
|
@ -4,7 +4,7 @@
|
||||
function! ale#handlers#writegood#ResetOptions() abort
|
||||
call ale#Set('writegood_options', '')
|
||||
call ale#Set('writegood_executable', 'write-good')
|
||||
call ale#Set('writegood_use_global', 0)
|
||||
call ale#Set('writegood_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
endfunction
|
||||
|
||||
" Reset the options so the tests can test how they are set.
|
||||
|
@ -1,6 +1,9 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Tools for managing command history
|
||||
|
||||
" A flag for controlling the maximum size of the command history to store.
|
||||
let g:ale_max_buffer_history_size = get(g:, 'ale_max_buffer_history_size', 20)
|
||||
|
||||
" Return a shallow copy of the command history for a given buffer number.
|
||||
function! ale#history#Get(buffer) abort
|
||||
return copy(getbufvar(a:buffer, 'ale_history', []))
|
||||
|
152
sources_non_forked/ale/autoload/ale/hover.vim
Normal file
152
sources_non_forked/ale/autoload/ale/hover.vim
Normal file
@ -0,0 +1,152 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Hover support for LSP linters.
|
||||
|
||||
let s:hover_map = {}
|
||||
|
||||
" Used to get the hover map in tests.
|
||||
function! ale#hover#GetMap() abort
|
||||
return deepcopy(s:hover_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the hover map in tests.
|
||||
function! ale#hover#SetMap(map) abort
|
||||
let s:hover_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#hover#ClearLSPData() abort
|
||||
let s:hover_map = {}
|
||||
endfunction
|
||||
|
||||
function! ale#hover#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') is# 'quickinfo'
|
||||
\&& has_key(s:hover_map, a:response.request_seq)
|
||||
let l:options = remove(s:hover_map, a:response.request_seq)
|
||||
|
||||
if get(a:response, 'success', v:false) is v:true
|
||||
\&& get(a:response, 'body', v:null) isnot v:null
|
||||
if get(l:options, 'hover_from_balloonexpr', 0)
|
||||
\&& exists('*balloon_show')
|
||||
\&& ale#Var(l:options.buffer, 'set_balloons')
|
||||
call balloon_show(a:response.body.displayString)
|
||||
else
|
||||
call ale#util#ShowMessage(a:response.body.displayString)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#hover#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:hover_map, a:response.id)
|
||||
let l:options = remove(s:hover_map, a:response.id)
|
||||
|
||||
" If the call did __not__ come from balloonexpr...
|
||||
if !get(l:options, 'hover_from_balloonexpr', 0)
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getcurpos()[1:2]
|
||||
let l:end = len(getline(l:line))
|
||||
|
||||
if l:buffer isnot l:options.buffer
|
||||
\|| l:line isnot l:options.line
|
||||
\|| min([l:column, l:end]) isnot min([l:options.column, l:end])
|
||||
" ... Cancel display the message if the cursor has moved.
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
" The result can be a Dictionary item, a List of the same, or null.
|
||||
let l:result = get(a:response, 'result', v:null)
|
||||
|
||||
if l:result is v:null
|
||||
return
|
||||
endif
|
||||
|
||||
let l:result = l:result.contents
|
||||
|
||||
if type(l:result) is type('')
|
||||
" The result can be just a string.
|
||||
let l:result = [l:result]
|
||||
endif
|
||||
|
||||
if type(l:result) is type({})
|
||||
" If the result is an object, then it's markup content.
|
||||
let l:result = [l:result.value]
|
||||
endif
|
||||
|
||||
if type(l:result) is type([])
|
||||
" Replace objects with text values.
|
||||
call map(l:result, 'type(v:val) is type('''') ? v:val : v:val.value')
|
||||
let l:str = join(l:result, "\n")
|
||||
let l:str = substitute(l:str, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||
|
||||
if !empty(l:str)
|
||||
if get(l:options, 'hover_from_balloonexpr', 0)
|
||||
\&& exists('*balloon_show')
|
||||
\&& ale#Var(l:options.buffer, 'set_balloons')
|
||||
call balloon_show(l:str)
|
||||
else
|
||||
call ale#util#ShowMessage(l:str)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ShowDetails(linter, buffer, line, column, opt) abort
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#hover#HandleTSServerResponse')
|
||||
\ : function('ale#hover#HandleLSPResponse')
|
||||
|
||||
let l:lsp_details = ale#linter#StartLSP(a:buffer, a:linter, l:Callback)
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:id = l:lsp_details.connection_id
|
||||
let l:root = l:lsp_details.project_root
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:column = a:column
|
||||
|
||||
let l:message = ale#lsp#tsserver_message#Quickinfo(
|
||||
\ a:buffer,
|
||||
\ a:line,
|
||||
\ l:column
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, or the
|
||||
" hover position probably won't make sense.
|
||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(a:buffer), l:root)
|
||||
|
||||
let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])])
|
||||
|
||||
let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column)
|
||||
endif
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
||||
|
||||
let s:hover_map[l:request_id] = {
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'line': a:line,
|
||||
\ 'column': l:column,
|
||||
\ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" Obtain Hover information for the specified position
|
||||
" Pass optional arguments in the dictionary opt.
|
||||
" Currently, only one key/value is useful:
|
||||
" - called_from_balloonexpr, this flag marks if we want the result from this
|
||||
" ale#hover#Show to display in a balloon if possible
|
||||
"
|
||||
" Currently, the callbacks displays the info from hover :
|
||||
" - in the balloon if opt.called_from_balloonexpr and balloon_show is detected
|
||||
" - as status message otherwise
|
||||
function! ale#hover#Show(buffer, line, col, opt) abort
|
||||
for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
||||
if !empty(l:linter.lsp)
|
||||
call s:ShowDetails(l:linter, a:buffer, a:line, a:col, a:opt)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
@ -8,6 +8,9 @@
|
||||
" ale#job#IsRunning(job_id) -> 1 if running, 0 otherwise.
|
||||
" ale#job#Stop(job_id)
|
||||
|
||||
" A setting for wrapping commands.
|
||||
let g:ale_command_wrapper = get(g:, 'ale_command_wrapper', '')
|
||||
|
||||
if !has_key(s:, 'job_map')
|
||||
let s:job_map = {}
|
||||
endif
|
||||
@ -119,7 +122,7 @@ function! s:VimCloseCallback(channel) abort
|
||||
if job_status(l:job) is# 'dead'
|
||||
try
|
||||
if !empty(l:info) && has_key(l:info, 'exit_cb')
|
||||
call ale#util#GetFunction(l:info.exit_cb)(l:job_id, l:info.exit_code)
|
||||
call ale#util#GetFunction(l:info.exit_cb)(l:job_id, get(l:info, 'exit_code', 1))
|
||||
endif
|
||||
finally
|
||||
" Automatically forget about the job after it's done.
|
||||
@ -208,7 +211,7 @@ function! ale#job#PrepareCommand(buffer, command) abort
|
||||
return 'cmd /s/c "' . l:command . '"'
|
||||
endif
|
||||
|
||||
if &shell =~? 'fish$'
|
||||
if &shell =~? 'fish$\|pwsh$'
|
||||
return ['/bin/sh', '-c', l:command]
|
||||
endif
|
||||
|
||||
|
@ -3,15 +3,19 @@ call ale#Set('wrap_command_as_one_argument', 0)
|
||||
" Description: Linter registration and lazy-loading
|
||||
" Retrieves linters as requested by the engine, loading them if needed.
|
||||
|
||||
let s:runtime_loaded_map = {}
|
||||
let s:linters = {}
|
||||
|
||||
" Default filetype aliases.
|
||||
" The user defined aliases will be merged with this Dictionary.
|
||||
"
|
||||
" NOTE: Update the g:ale_linter_aliases documentation when modifying this.
|
||||
let s:default_ale_linter_aliases = {
|
||||
\ 'Dockerfile': 'dockerfile',
|
||||
\ 'csh': 'sh',
|
||||
\ 'plaintex': 'tex',
|
||||
\ 'systemverilog': 'verilog',
|
||||
\ 'vimwiki': 'markdown',
|
||||
\ 'zsh': 'sh',
|
||||
\}
|
||||
|
||||
@ -38,6 +42,7 @@ let s:default_ale_linters = {
|
||||
|
||||
" Testing/debugging helper to unload all linters.
|
||||
function! ale#linter#Reset() abort
|
||||
let s:runtime_loaded_map = {}
|
||||
let s:linters = {}
|
||||
endfunction
|
||||
|
||||
@ -49,6 +54,10 @@ function! s:IsBoolean(value) abort
|
||||
return type(a:value) == type(0) && (a:value == 0 || a:value == 1)
|
||||
endfunction
|
||||
|
||||
function! s:LanguageGetter(buffer) dict abort
|
||||
return l:self.language
|
||||
endfunction
|
||||
|
||||
function! ale#linter#PreProcess(linter) abort
|
||||
if type(a:linter) != type({})
|
||||
throw 'The linter object must be a Dictionary'
|
||||
@ -183,10 +192,26 @@ function! ale#linter#PreProcess(linter) abort
|
||||
endif
|
||||
|
||||
if l:needs_lsp_details
|
||||
let l:obj.language_callback = get(a:linter, 'language_callback')
|
||||
if has_key(a:linter, 'language')
|
||||
if has_key(a:linter, 'language_callback')
|
||||
throw 'Only one of `language` or `language_callback` '
|
||||
\ . 'should be set'
|
||||
endif
|
||||
|
||||
if !s:IsCallback(l:obj.language_callback)
|
||||
throw '`language_callback` must be a callback for LSP linters'
|
||||
let l:obj.language = get(a:linter, 'language')
|
||||
|
||||
if type(l:obj.language) != type('')
|
||||
throw '`language` must be a string'
|
||||
endif
|
||||
|
||||
" Make 'language_callback' return the 'language' value.
|
||||
let l:obj.language_callback = function('s:LanguageGetter')
|
||||
else
|
||||
let l:obj.language_callback = get(a:linter, 'language_callback')
|
||||
|
||||
if !s:IsCallback(l:obj.language_callback)
|
||||
throw '`language_callback` must be a callback for LSP linters'
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:obj.project_root_callback = get(a:linter, 'project_root_callback')
|
||||
@ -194,6 +219,29 @@ function! ale#linter#PreProcess(linter) abort
|
||||
if !s:IsCallback(l:obj.project_root_callback)
|
||||
throw '`project_root_callback` must be a callback for LSP linters'
|
||||
endif
|
||||
|
||||
if has_key(a:linter, 'completion_filter')
|
||||
let l:obj.completion_filter = a:linter.completion_filter
|
||||
|
||||
if !s:IsCallback(l:obj.completion_filter)
|
||||
throw '`completion_filter` must be a callback'
|
||||
endif
|
||||
endif
|
||||
|
||||
if has_key(a:linter, 'initialization_options_callback')
|
||||
if has_key(a:linter, 'initialization_options')
|
||||
throw 'Only one of `initialization_options` or '
|
||||
\ . '`initialization_options_callback` should be set'
|
||||
endif
|
||||
|
||||
let l:obj.initialization_options_callback = a:linter.initialization_options_callback
|
||||
|
||||
if !s:IsCallback(l:obj.initialization_options_callback)
|
||||
throw '`initialization_options_callback` must be a callback if defined'
|
||||
endif
|
||||
elseif has_key(a:linter, 'initialization_options')
|
||||
let l:obj.initialization_options = a:linter.initialization_options
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout')
|
||||
@ -242,20 +290,20 @@ function! ale#linter#Define(filetype, linter) abort
|
||||
call add(s:linters[a:filetype], l:new_linter)
|
||||
endfunction
|
||||
|
||||
" Prevent any linters from being loaded for a given filetype.
|
||||
function! ale#linter#PreventLoading(filetype) abort
|
||||
let s:runtime_loaded_map[a:filetype] = 1
|
||||
endfunction
|
||||
|
||||
function! ale#linter#GetAll(filetypes) abort
|
||||
let l:combined_linters = []
|
||||
|
||||
for l:filetype in a:filetypes
|
||||
" Load linter defintions from files if we haven't loaded them yet.
|
||||
if !has_key(s:linters, l:filetype)
|
||||
" Load linters from runtimepath if we haven't done that yet.
|
||||
if !has_key(s:runtime_loaded_map, l:filetype)
|
||||
execute 'silent! runtime! ale_linters/' . l:filetype . '/*.vim'
|
||||
|
||||
" Always set an empty List for the loaded linters if we don't find
|
||||
" any. This will prevent us from executing the runtime command
|
||||
" many times, redundantly.
|
||||
if !has_key(s:linters, l:filetype)
|
||||
let s:linters[l:filetype] = []
|
||||
endif
|
||||
let s:runtime_loaded_map[l:filetype] = 1
|
||||
endif
|
||||
|
||||
call extend(l:combined_linters, get(s:linters, l:filetype, []))
|
||||
@ -418,12 +466,20 @@ function! ale#linter#StartLSP(buffer, linter, callback) abort
|
||||
return {}
|
||||
endif
|
||||
|
||||
let l:initialization_options = {}
|
||||
if has_key(a:linter, 'initialization_options_callback')
|
||||
let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
|
||||
elseif has_key(a:linter, 'initialization_options')
|
||||
let l:initialization_options = a:linter.initialization_options
|
||||
endif
|
||||
|
||||
if a:linter.lsp is# 'socket'
|
||||
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
|
||||
let l:conn_id = ale#lsp#ConnectToAddress(
|
||||
\ l:address,
|
||||
\ l:root,
|
||||
\ a:callback,
|
||||
\ l:initialization_options,
|
||||
\)
|
||||
else
|
||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||
@ -441,6 +497,7 @@ function! ale#linter#StartLSP(buffer, linter, callback) abort
|
||||
\ l:command,
|
||||
\ l:root,
|
||||
\ a:callback,
|
||||
\ l:initialization_options,
|
||||
\)
|
||||
endif
|
||||
|
||||
|
@ -1,6 +1,19 @@
|
||||
" Author: Bjorn Neergaard <bjorn@neersighted.com>, modified by Yann fery <yann@fery.me>
|
||||
" Description: Manages the loclist and quickfix lists
|
||||
|
||||
" This flag dictates if ale open the configured loclist
|
||||
let g:ale_open_list = get(g:, 'ale_open_list', 0)
|
||||
" This flag dictates if ale keeps open loclist even if there is no error in loclist
|
||||
let g:ale_keep_list_window_open = get(g:, 'ale_keep_list_window_open', 0)
|
||||
" This flag dictates that quickfix windows should be opened vertically
|
||||
let g:ale_list_vertical = get(g:, 'ale_list_vertical', 0)
|
||||
" The window size to set for the quickfix and loclist windows
|
||||
let g:ale_list_window_size = get(g:, 'ale_list_window_size', 10)
|
||||
" A string format for the loclist messages.
|
||||
let g:ale_loclist_msg_format = get(g:, 'ale_loclist_msg_format',
|
||||
\ get(g:, 'ale_echo_msg_format', '%code: %%s')
|
||||
\)
|
||||
|
||||
if !exists('s:timer_args')
|
||||
let s:timer_args = {}
|
||||
endif
|
||||
|
@ -6,7 +6,7 @@
|
||||
let s:connections = []
|
||||
let g:ale_lsp_next_message_id = 1
|
||||
|
||||
function! s:NewConnection() abort
|
||||
function! s:NewConnection(initialization_options) abort
|
||||
" id: The job ID as a Number, or the server address as a string.
|
||||
" data: The message data received so far.
|
||||
" executable: An executable only set for program connections.
|
||||
@ -18,6 +18,7 @@ function! s:NewConnection() abort
|
||||
\ 'projects': {},
|
||||
\ 'open_documents': [],
|
||||
\ 'callback_list': [],
|
||||
\ 'initialization_options': a:initialization_options,
|
||||
\}
|
||||
|
||||
call add(s:connections, l:conn)
|
||||
@ -207,6 +208,11 @@ function! ale#lsp#HandleOtherInitializeResponses(conn, response) abort
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#HandleMessage(conn, message) abort
|
||||
if type(a:message) != type('')
|
||||
" Ignore messages that aren't strings.
|
||||
return
|
||||
endif
|
||||
|
||||
let a:conn.data .= a:message
|
||||
|
||||
" Parse the objects now if we can, and keep the remaining text.
|
||||
@ -266,7 +272,7 @@ endfunction
|
||||
"
|
||||
" The job ID will be returned for for the program if it ran, otherwise
|
||||
" 0 will be returned.
|
||||
function! ale#lsp#StartProgram(executable, command, project_root, callback) abort
|
||||
function! ale#lsp#StartProgram(executable, command, project_root, callback, initialization_options) abort
|
||||
if !executable(a:executable)
|
||||
return 0
|
||||
endif
|
||||
@ -274,7 +280,7 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback) abor
|
||||
let l:conn = s:FindConnection('executable', a:executable)
|
||||
|
||||
" Get the current connection or a new one.
|
||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection()
|
||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection(a:initialization_options)
|
||||
let l:conn.executable = a:executable
|
||||
|
||||
if !has_key(l:conn, 'id') || !ale#job#IsRunning(l:conn.id)
|
||||
@ -300,10 +306,10 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback) abor
|
||||
endfunction
|
||||
|
||||
" Connect to an address and set up a callback for handling responses.
|
||||
function! ale#lsp#ConnectToAddress(address, project_root, callback) abort
|
||||
function! ale#lsp#ConnectToAddress(address, project_root, callback, initialization_options) abort
|
||||
let l:conn = s:FindConnection('id', a:address)
|
||||
" Get the current connection or a new one.
|
||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection()
|
||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection(a:initialization_options)
|
||||
|
||||
if !has_key(l:conn, 'channel') || ch_status(l:conn.channel) isnot# 'open'
|
||||
let l:conn.channnel = ch_open(a:address, {
|
||||
@ -378,7 +384,7 @@ function! ale#lsp#Send(conn_id, message, ...) abort
|
||||
" Only send the init message once.
|
||||
if !l:project.init_request_id
|
||||
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
|
||||
\ ale#lsp#message#Initialize(l:project_root),
|
||||
\ ale#lsp#message#Initialize(l:project_root, l:conn.initialization_options),
|
||||
\)
|
||||
|
||||
let l:project.init_request_id = l:init_id
|
||||
|
@ -24,12 +24,15 @@ function! ale#lsp#message#GetNextVersionID() abort
|
||||
return l:id
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Initialize(root_path) abort
|
||||
function! ale#lsp#message#Initialize(root_path, initialization_options) abort
|
||||
" TODO: Define needed capabilities.
|
||||
" NOTE: rootPath is deprecated in favour of rootUri
|
||||
return [0, 'initialize', {
|
||||
\ 'processId': getpid(),
|
||||
\ 'rootPath': a:root_path,
|
||||
\ 'capabilities': {},
|
||||
\ 'initializationOptions': a:initialization_options,
|
||||
\ 'rootUri': ale#path#ToURI(a:root_path),
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
@ -116,3 +119,22 @@ function! ale#lsp#message#Definition(buffer, line, column) abort
|
||||
\ 'position': {'line': a:line - 1, 'character': a:column},
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#References(buffer, line, column) abort
|
||||
return [0, 'textDocument/references', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
|
||||
\ },
|
||||
\ 'position': {'line': a:line - 1, 'character': a:column},
|
||||
\ 'context': {'includeDeclaration': v:false},
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Hover(buffer, line, column) abort
|
||||
return [0, 'textDocument/hover', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
|
||||
\ },
|
||||
\ 'position': {'line': a:line - 1, 'character': a:column},
|
||||
\}]
|
||||
endfunction
|
||||
|
@ -1,6 +1,20 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Parsing and transforming of LSP server responses.
|
||||
|
||||
" Constants for error codes.
|
||||
" Defined by JSON RPC
|
||||
let s:PARSE_ERROR = -32700
|
||||
let s:INVALID_REQUEST = -32600
|
||||
let s:METHOD_NOT_FOUND = -32601
|
||||
let s:INVALID_PARAMS = -32602
|
||||
let s:INTERNAL_ERROR = -32603
|
||||
let s:SERVER_ERROR_START = -32099
|
||||
let s:SERVER_ERROR_END = -32000
|
||||
let s:SERVER_NOT_INITIALIZED = -32002
|
||||
let s:UNKNOWN_ERROR_CODE = -32001
|
||||
" Defined by the protocol.
|
||||
let s:REQUEST_CANCELLED = -32800
|
||||
|
||||
" Constants for message severity codes.
|
||||
let s:SEVERITY_ERROR = 1
|
||||
let s:SEVERITY_WARNING = 2
|
||||
@ -72,3 +86,31 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
|
||||
|
||||
return l:loclist
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#response#GetErrorMessage(response) abort
|
||||
if type(get(a:response, 'error', 0)) isnot type({})
|
||||
return ''
|
||||
endif
|
||||
|
||||
let l:code = get(a:response.error, 'code')
|
||||
|
||||
" Only report things for these error codes.
|
||||
if l:code isnot s:INVALID_PARAMS && l:code isnot s:INTERNAL_ERROR
|
||||
return ''
|
||||
endif
|
||||
|
||||
let l:message = get(a:response.error, 'message', '')
|
||||
|
||||
if empty(l:message)
|
||||
return ''
|
||||
endif
|
||||
|
||||
" Include the traceback as details, if it's there.
|
||||
let l:traceback = get(get(a:response.error, 'data', {}), 'traceback', [])
|
||||
|
||||
if type(l:traceback) is type([]) && !empty(l:traceback)
|
||||
let l:message .= "\n" . join(l:traceback, "\n")
|
||||
endif
|
||||
|
||||
return l:message
|
||||
endfunction
|
||||
|
@ -61,3 +61,19 @@ function! ale#lsp#tsserver_message#Definition(buffer, line, column) abort
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#References(buffer, line, column) abort
|
||||
return [0, 'ts@references', {
|
||||
\ 'line': a:line,
|
||||
\ 'offset': a:column,
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#Quickinfo(buffer, line, column) abort
|
||||
return [0, 'ts@quickinfo', {
|
||||
\ 'line': a:line,
|
||||
\ 'offset': a:column,
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\}]
|
||||
endfunction
|
||||
|
@ -1,6 +1,11 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Set options in files based on regex patterns.
|
||||
|
||||
" A dictionary mapping regular expression patterns to arbitrary buffer
|
||||
" variables to be set. Useful for configuring ALE based on filename patterns.
|
||||
let g:ale_pattern_options = get(g:, 'ale_pattern_options', {})
|
||||
let g:ale_pattern_options_enabled = get(g:, 'ale_pattern_options_enabled', !empty(g:ale_pattern_options))
|
||||
|
||||
" These variables are used to cache the sorting of patterns below.
|
||||
let s:last_pattern_options = {}
|
||||
let s:sorted_items = []
|
||||
@ -18,7 +23,8 @@ function! s:CmpPatterns(left_item, right_item) abort
|
||||
endfunction
|
||||
|
||||
function! ale#pattern_options#SetOptions(buffer) abort
|
||||
if !g:ale_pattern_options_enabled || empty(g:ale_pattern_options)
|
||||
if !get(g:, 'ale_pattern_options_enabled', 0)
|
||||
\|| empty(get(g:, 'ale_pattern_options', 0))
|
||||
return
|
||||
endif
|
||||
|
||||
|
@ -2,13 +2,16 @@
|
||||
" Description: Preview windows for showing whatever information in.
|
||||
|
||||
" Open a preview window and show some lines in it.
|
||||
function! ale#preview#Show(lines) abort
|
||||
" An optional second argument can set an alternative filetype for the window.
|
||||
function! ale#preview#Show(lines, ...) abort
|
||||
let l:filetype = get(a:000, 0, 'ale-preview')
|
||||
|
||||
silent pedit ALEPreviewWindow
|
||||
wincmd P
|
||||
setlocal modifiable
|
||||
setlocal noreadonly
|
||||
setlocal nobuflisted
|
||||
setlocal filetype=ale-preview
|
||||
let &l:filetype = l:filetype
|
||||
setlocal buftype=nofile
|
||||
setlocal bufhidden=wipe
|
||||
:%d
|
||||
@ -16,3 +19,50 @@ function! ale#preview#Show(lines) abort
|
||||
setlocal nomodifiable
|
||||
setlocal readonly
|
||||
endfunction
|
||||
|
||||
" Show a location selection preview window, given some items.
|
||||
" Each item should have 'filename', 'line', and 'column' keys.
|
||||
function! ale#preview#ShowSelection(item_list) abort
|
||||
let l:lines = []
|
||||
|
||||
" Create lines to display to users.
|
||||
for l:item in a:item_list
|
||||
call add(
|
||||
\ l:lines,
|
||||
\ l:item.filename
|
||||
\ . ':' . l:item.line
|
||||
\ . ':' . l:item.column,
|
||||
\)
|
||||
endfor
|
||||
|
||||
call ale#preview#Show(l:lines, 'ale-preview-selection')
|
||||
let b:ale_preview_item_list = a:item_list
|
||||
endfunction
|
||||
|
||||
function! s:Open(open_in_tab) abort
|
||||
let l:item_list = get(b:, 'ale_preview_item_list', [])
|
||||
let l:item = get(l:item_list, getcurpos()[1] - 1, {})
|
||||
|
||||
if empty(l:item)
|
||||
return
|
||||
endif
|
||||
|
||||
if !a:open_in_tab
|
||||
:q!
|
||||
endif
|
||||
|
||||
call ale#util#Open(
|
||||
\ l:item.filename,
|
||||
\ l:item.line,
|
||||
\ l:item.column,
|
||||
\ {'open_in_tab': a:open_in_tab},
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#preview#OpenSelectionInBuffer() abort
|
||||
call s:Open(0)
|
||||
endfunction
|
||||
|
||||
function! ale#preview#OpenSelectionInTab() abort
|
||||
call s:Open(1)
|
||||
endfunction
|
||||
|
@ -15,6 +15,7 @@ let g:ale_virtualenv_dir_names = get(g:, 'ale_virtualenv_dir_names', [
|
||||
|
||||
function! ale#python#FindProjectRootIni(buffer) abort
|
||||
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
|
||||
" If you change this, update ale-python-root documentation.
|
||||
if filereadable(l:path . '/MANIFEST.in')
|
||||
\|| filereadable(l:path . '/setup.cfg')
|
||||
\|| filereadable(l:path . '/pytest.ini')
|
||||
|
111
sources_non_forked/ale/autoload/ale/references.vim
Normal file
111
sources_non_forked/ale/autoload/ale/references.vim
Normal file
@ -0,0 +1,111 @@
|
||||
let s:references_map = {}
|
||||
|
||||
" Used to get the references map in tests.
|
||||
function! ale#references#GetMap() abort
|
||||
return deepcopy(s:references_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the references map in tests.
|
||||
function! ale#references#SetMap(map) abort
|
||||
let s:references_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#references#ClearLSPData() abort
|
||||
let s:references_map = {}
|
||||
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)
|
||||
call remove(s:references_map, a:response.request_seq)
|
||||
|
||||
if get(a:response, 'success', v:false) is v:true
|
||||
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,
|
||||
\})
|
||||
endfor
|
||||
|
||||
if empty(l:item_list)
|
||||
call ale#util#Execute('echom ''No references found.''')
|
||||
else
|
||||
call ale#preview#ShowSelection(l:item_list)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#references#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:references_map, a:response.id)
|
||||
call remove(s:references_map, a:response.id)
|
||||
|
||||
" The result can be a Dictionary item, a List of the same, or null.
|
||||
let l:result = get(a:response, 'result', [])
|
||||
let l:item_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,
|
||||
\})
|
||||
endfor
|
||||
|
||||
if empty(l:item_list)
|
||||
call ale#util#Execute('echom ''No references found.''')
|
||||
else
|
||||
call ale#preview#ShowSelection(l:item_list)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:FindReferences(linter) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getcurpos()[1:2]
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#references#HandleTSServerResponse')
|
||||
\ : function('ale#references#HandleLSPResponse')
|
||||
|
||||
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:id = l:lsp_details.connection_id
|
||||
let l:root = l:lsp_details.project_root
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:message = ale#lsp#tsserver_message#References(
|
||||
\ l:buffer,
|
||||
\ l:line,
|
||||
\ l:column
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, or the
|
||||
" references position probably won't make sense.
|
||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
|
||||
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
|
||||
let l:message = ale#lsp#message#References(l:buffer, l:line, l:column)
|
||||
endif
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
||||
|
||||
let s:references_map[l:request_id] = {}
|
||||
endfunction
|
||||
|
||||
function! ale#references#Find() abort
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:FindReferences(l:linter)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
@ -2,6 +2,25 @@ scriptencoding utf8
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Draws error and warning signs into signcolumn
|
||||
|
||||
" This flag can be set to some integer to control the maximum number of signs
|
||||
" that ALE will set.
|
||||
let g:ale_max_signs = get(g:, 'ale_max_signs', -1)
|
||||
" This flag can be set to 1 to enable changing the sign column colors when
|
||||
" there are errors.
|
||||
let g:ale_change_sign_column_color = get(g:, 'ale_change_sign_column_color', 0)
|
||||
" These variables dictate what signs are used to indicate errors and warnings.
|
||||
let g:ale_sign_error = get(g:, 'ale_sign_error', '>>')
|
||||
let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error)
|
||||
let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--')
|
||||
let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning)
|
||||
let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
|
||||
" This variable sets an offset which can be set for sign IDs.
|
||||
" This ID can be changed depending on what IDs are set for other plugins.
|
||||
" The dummy sign will use the ID exactly equal to the offset.
|
||||
let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
|
||||
" This flag can be set to 1 to keep sign gutter always open
|
||||
let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
|
||||
|
||||
if !hlexists('ALEErrorSign')
|
||||
highlight link ALEErrorSign error
|
||||
endif
|
||||
@ -60,55 +79,35 @@ execute 'sign define ALEInfoSign text=' . g:ale_sign_info
|
||||
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
|
||||
sign define ALEDummySign
|
||||
|
||||
let s:error_priority = 1
|
||||
let s:warning_priority = 2
|
||||
let s:info_priority = 3
|
||||
let s:style_error_priority = 4
|
||||
let s:style_warning_priority = 5
|
||||
|
||||
function! ale#sign#GetSignName(sublist) abort
|
||||
let l:priority = s:style_warning_priority
|
||||
let l:priority = g:ale#util#style_warning_priority
|
||||
|
||||
" Determine the highest priority item for the line.
|
||||
for l:item in a:sublist
|
||||
if l:item.type is# 'I'
|
||||
let l:item_priority = s:info_priority
|
||||
elseif l:item.type is# 'W'
|
||||
if get(l:item, 'sub_type', '') is# 'style'
|
||||
let l:item_priority = s:style_warning_priority
|
||||
else
|
||||
let l:item_priority = s:warning_priority
|
||||
endif
|
||||
else
|
||||
if get(l:item, 'sub_type', '') is# 'style'
|
||||
let l:item_priority = s:style_error_priority
|
||||
else
|
||||
let l:item_priority = s:error_priority
|
||||
endif
|
||||
endif
|
||||
let l:item_priority = ale#util#GetItemPriority(l:item)
|
||||
|
||||
if l:item_priority < l:priority
|
||||
if l:item_priority > l:priority
|
||||
let l:priority = l:item_priority
|
||||
endif
|
||||
endfor
|
||||
|
||||
if l:priority is# s:error_priority
|
||||
if l:priority is# g:ale#util#error_priority
|
||||
return 'ALEErrorSign'
|
||||
endif
|
||||
|
||||
if l:priority is# s:warning_priority
|
||||
if l:priority is# g:ale#util#warning_priority
|
||||
return 'ALEWarningSign'
|
||||
endif
|
||||
|
||||
if l:priority is# s:style_error_priority
|
||||
if l:priority is# g:ale#util#style_error_priority
|
||||
return 'ALEStyleErrorSign'
|
||||
endif
|
||||
|
||||
if l:priority is# s:style_warning_priority
|
||||
if l:priority is# g:ale#util#style_warning_priority
|
||||
return 'ALEStyleWarningSign'
|
||||
endif
|
||||
|
||||
if l:priority is# s:info_priority
|
||||
if l:priority is# g:ale#util#info_priority
|
||||
return 'ALEInfoSign'
|
||||
endif
|
||||
|
||||
|
@ -1,6 +1,14 @@
|
||||
" Author: KabbAmine <amine.kabb@gmail.com>
|
||||
" Description: Statusline related function(s)
|
||||
|
||||
" remove in 2.0
|
||||
"
|
||||
" A deprecated setting for ale#statusline#Status()
|
||||
" See :help ale#statusline#Count() for getting status reports.
|
||||
let g:ale_statusline_format = get(g:, 'ale_statusline_format',
|
||||
\ ['%d error(s)', '%d warning(s)', 'OK']
|
||||
\)
|
||||
|
||||
function! s:CreateCountDict() abort
|
||||
" Keys 0 and 1 are for backwards compatibility.
|
||||
" The count object used to be a List of [error_count, warning_count].
|
||||
@ -90,6 +98,8 @@ function! s:StatusForListFormat() abort
|
||||
return l:res
|
||||
endfunction
|
||||
|
||||
" remove in 2.0
|
||||
"
|
||||
" Returns a formatted string that can be integrated in the statusline.
|
||||
"
|
||||
" This function is deprecated, and should not be used. Use the airline plugin
|
||||
|
@ -1,84 +1,6 @@
|
||||
function! ale#toggle#InitAuGroups() abort
|
||||
" This value used to be a Boolean as a Number, and is now a String.
|
||||
let l:text_changed = '' . g:ale_lint_on_text_changed
|
||||
|
||||
augroup ALEPatternOptionsGroup
|
||||
autocmd!
|
||||
autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand('<abuf>')))
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnTextChangedGroup
|
||||
autocmd!
|
||||
if g:ale_enabled
|
||||
if l:text_changed is? 'always' || l:text_changed is# '1'
|
||||
autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||
elseif l:text_changed is? 'normal'
|
||||
autocmd TextChanged * call ale#Queue(g:ale_lint_delay)
|
||||
elseif l:text_changed is? 'insert'
|
||||
autocmd TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||
endif
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnEnterGroup
|
||||
autocmd!
|
||||
if g:ale_enabled
|
||||
" Handle everything that needs to happen when buffers are entered.
|
||||
autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
if g:ale_enabled && g:ale_lint_on_enter
|
||||
autocmd BufWinEnter,BufRead * call ale#Queue(0, 'lint_file', str2nr(expand('<abuf>')))
|
||||
" Track when the file is changed outside of Vim.
|
||||
autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnFiletypeChangeGroup
|
||||
autocmd!
|
||||
if g:ale_enabled && g:ale_lint_on_filetype_changed
|
||||
" Only start linting if the FileType actually changes after
|
||||
" opening a buffer. The FileType will fire when buffers are opened.
|
||||
autocmd FileType * call ale#events#FileTypeEvent(
|
||||
\ str2nr(expand('<abuf>')),
|
||||
\ expand('<amatch>')
|
||||
\)
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnSaveGroup
|
||||
autocmd!
|
||||
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
|
||||
augroup END
|
||||
|
||||
augroup ALERunOnInsertLeave
|
||||
autocmd!
|
||||
if g:ale_enabled && g:ale_lint_on_insert_leave
|
||||
autocmd InsertLeave * call ale#Queue(0)
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup ALECursorGroup
|
||||
autocmd!
|
||||
if g:ale_enabled && g:ale_echo_cursor
|
||||
autocmd CursorMoved,CursorHold * call ale#cursor#EchoCursorWarningWithDelay()
|
||||
" Look for a warning to echo as soon as we leave Insert mode.
|
||||
" The script's position variable used when moving the cursor will
|
||||
" not be changed here.
|
||||
autocmd InsertLeave * call ale#cursor#EchoCursorWarning()
|
||||
endif
|
||||
augroup END
|
||||
|
||||
if !g:ale_enabled
|
||||
augroup! ALERunOnTextChangedGroup
|
||||
augroup! ALERunOnEnterGroup
|
||||
augroup! ALERunOnInsertLeave
|
||||
augroup! ALECursorGroup
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:EnablePreamble() abort
|
||||
" Set pattern options again, if enabled.
|
||||
if g:ale_pattern_options_enabled
|
||||
if get(g:, 'ale_pattern_options_enabled', 0)
|
||||
call ale#pattern_options#SetOptions(bufnr(''))
|
||||
endif
|
||||
|
||||
@ -126,16 +48,11 @@ function! ale#toggle#Toggle() abort
|
||||
endif
|
||||
endif
|
||||
|
||||
call ale#toggle#InitAuGroups()
|
||||
call ale#autocmd#InitAuGroups()
|
||||
endfunction
|
||||
|
||||
function! ale#toggle#Enable() abort
|
||||
if !g:ale_enabled
|
||||
" Set pattern options again, if enabled.
|
||||
if g:ale_pattern_options_enabled
|
||||
call ale#pattern_options#SetOptions(bufnr(''))
|
||||
endif
|
||||
|
||||
call ale#toggle#Toggle()
|
||||
endif
|
||||
endfunction
|
||||
|
@ -11,6 +11,25 @@ function! ale#util#FeedKeys(...) abort
|
||||
return call('feedkeys', a:000)
|
||||
endfunction
|
||||
|
||||
" Show a message in as small a window as possible.
|
||||
"
|
||||
" Vim 8 does not support echoing long messages from asynchronous callbacks,
|
||||
" but NeoVim does. Small messages can be echoed in Vim 8, and larger messages
|
||||
" have to be shown in preview windows.
|
||||
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'
|
||||
else
|
||||
call ale#preview#Show(split(a:string, "\n"))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" A wrapper function for execute, so we can test executing some commands.
|
||||
function! ale#util#Execute(expr) abort
|
||||
execute a:expr
|
||||
endfunction
|
||||
|
||||
if !exists('g:ale#util#nul_file')
|
||||
" A null file for sending output to nothing.
|
||||
let g:ale#util#nul_file = '/dev/null'
|
||||
@ -33,6 +52,42 @@ function! ale#util#GetFunction(string_or_ref) abort
|
||||
return a:string_or_ref
|
||||
endfunction
|
||||
|
||||
function! ale#util#Open(filename, line, column, options) abort
|
||||
if get(a:options, 'open_in_tab', 0)
|
||||
call ale#util#Execute('tabedit ' . fnameescape(a:filename))
|
||||
else
|
||||
call ale#util#Execute('edit ' . fnameescape(a:filename))
|
||||
endif
|
||||
|
||||
call cursor(a:line, a:column)
|
||||
endfunction
|
||||
|
||||
let g:ale#util#error_priority = 5
|
||||
let g:ale#util#warning_priority = 4
|
||||
let g:ale#util#info_priority = 3
|
||||
let g:ale#util#style_error_priority = 2
|
||||
let g:ale#util#style_warning_priority = 1
|
||||
|
||||
function! ale#util#GetItemPriority(item) abort
|
||||
if a:item.type is# 'I'
|
||||
return g:ale#util#info_priority
|
||||
endif
|
||||
|
||||
if a:item.type is# 'W'
|
||||
if get(a:item, 'sub_type', '') is# 'style'
|
||||
return g:ale#util#style_warning_priority
|
||||
endif
|
||||
|
||||
return g:ale#util#warning_priority
|
||||
endif
|
||||
|
||||
if get(a:item, 'sub_type', '') is# 'style'
|
||||
return g:ale#util#style_error_priority
|
||||
endif
|
||||
|
||||
return g:ale#util#error_priority
|
||||
endfunction
|
||||
|
||||
" Compare two loclist items for ALE, sorted by their buffers, filenames, and
|
||||
" line numbers and column numbers.
|
||||
function! ale#util#LocItemCompare(left, right) abort
|
||||
@ -70,6 +125,23 @@ function! ale#util#LocItemCompare(left, right) abort
|
||||
return 1
|
||||
endif
|
||||
|
||||
" When either of the items lacks a problem type, then the two items should
|
||||
" be considered equal. This is important for loclist jumping.
|
||||
if !has_key(a:left, 'type') || !has_key(a:right, 'type')
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:left_priority = ale#util#GetItemPriority(a:left)
|
||||
let l:right_priority = ale#util#GetItemPriority(a:right)
|
||||
|
||||
if l:left_priority < l:right_priority
|
||||
return -1
|
||||
endif
|
||||
|
||||
if l:left_priority > l:right_priority
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
@ -139,6 +211,17 @@ function! ale#util#BinarySearch(loclist, buffer, line, column) abort
|
||||
let l:index += 1
|
||||
endwhile
|
||||
|
||||
" Scan forwards to find the last item on the column for the item
|
||||
" we found, which will have the most serious problem.
|
||||
let l:item_column = a:loclist[l:index].col
|
||||
|
||||
while l:index < l:max
|
||||
\&& a:loclist[l:index + 1].bufnr == a:buffer
|
||||
\&& a:loclist[l:index + 1].lnum == a:line
|
||||
\&& a:loclist[l:index + 1].col == l:item_column
|
||||
let l:index += 1
|
||||
endwhile
|
||||
|
||||
return l:index
|
||||
endif
|
||||
endwhile
|
||||
@ -287,8 +370,10 @@ if !exists('s:patial_timers')
|
||||
endif
|
||||
|
||||
function! s:ApplyPartialTimer(timer_id) abort
|
||||
let [l:Callback, l:args] = remove(s:partial_timers, a:timer_id)
|
||||
call call(l:Callback, [a:timer_id] + l:args)
|
||||
if has_key(s:partial_timers, a:timer_id)
|
||||
let [l:Callback, l:args] = remove(s:partial_timers, a:timer_id)
|
||||
call call(l:Callback, [a:timer_id] + l:args)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Given a delay, a callback, a List of arguments, start a timer with
|
||||
@ -311,3 +396,13 @@ function! ale#util#StopPartialTimer(timer_id) abort
|
||||
call remove(s:partial_timers, a:timer_id)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Given a possibly multi-byte string and a 1-based character position on a
|
||||
" line, return the 1-based byte position on that line.
|
||||
function! ale#util#Col(str, chr) abort
|
||||
if a:chr < 2
|
||||
return a:chr
|
||||
endif
|
||||
|
||||
return strlen(join(split(a:str, '\zs')[0:a:chr - 2], '')) + 1
|
||||
endfunction
|
||||
|
Reference in New Issue
Block a user