mirror of
https://github.com/amix/vimrc
synced 2025-07-12 06:05:01 +08:00
Updated plugins
This commit is contained in:
@ -7,9 +7,6 @@ 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_log_str = get(g:, 'ale_echo_msg_log_str', 'Log')
|
||||
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
||||
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
|
||||
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
|
||||
let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0)
|
||||
|
||||
" LSP window/showMessage format
|
||||
let g:ale_lsp_show_message_format = get(g:, 'ale_lsp_show_message_format', '%severity%:%linter%: %s')
|
||||
@ -100,7 +97,24 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
|
||||
" Use the filetype from the buffer
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
let l:linters = ale#linter#Get(l:filetype)
|
||||
let l:linters = ale#linter#RemoveIgnored(a:buffer, l:filetype, l:linters)
|
||||
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
" Load code to ignore linters only if we need to.
|
||||
if (
|
||||
\ !empty(l:ignore_config)
|
||||
\ || l:disable_lsp is 1
|
||||
\ || l:disable_lsp is v:true
|
||||
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
|
||||
\)
|
||||
let l:linters = ale#engine#ignore#Exclude(
|
||||
\ l:filetype,
|
||||
\ l:linters,
|
||||
\ l:ignore_config,
|
||||
\ l:disable_lsp,
|
||||
\)
|
||||
endif
|
||||
|
||||
" Tell other sources that they can start checking the buffer now.
|
||||
let g:ale_want_results_buffer = a:buffer
|
||||
@ -208,7 +222,7 @@ endfunction
|
||||
" valid for cmd on Windows, or most shells on Unix.
|
||||
function! ale#Env(variable_name, value) abort
|
||||
if has('win32')
|
||||
return 'set ' . a:variable_name . '=' . ale#Escape(a:value) . ' && '
|
||||
return 'set ' . ale#Escape(a:variable_name . '=' . a:value) . ' && '
|
||||
endif
|
||||
|
||||
return a:variable_name . '=' . ale#Escape(a:value) . ' '
|
||||
|
@ -339,17 +339,7 @@ function! ale#code_action#GetCodeActions(options) abort
|
||||
silent! aunmenu PopUp.Refactor\.\.\.
|
||||
|
||||
" Only display the menu items if there's an LSP server.
|
||||
let l:has_lsp = 0
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
let l:has_lsp = 1
|
||||
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
if l:has_lsp
|
||||
if len(ale#lsp_linter#GetEnabled(bufnr(''))) > 0
|
||||
if !empty(expand('<cword>'))
|
||||
silent! anoremenu <silent> PopUp.Rename :ALERename<CR>
|
||||
endif
|
||||
|
@ -473,15 +473,9 @@ function! ale#codefix#Execute(range, ...) abort
|
||||
endif
|
||||
|
||||
let l:MenuCallback = get(a:000, 0, v:null)
|
||||
let l:lsp_linters = []
|
||||
let l:linters = ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call add(l:lsp_linters, l:linter)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if empty(l:lsp_linters)
|
||||
if empty(l:linters)
|
||||
if l:MenuCallback is v:null
|
||||
call s:message('No active LSPs')
|
||||
else
|
||||
@ -491,7 +485,7 @@ function! ale#codefix#Execute(range, ...) abort
|
||||
return
|
||||
endif
|
||||
|
||||
for l:lsp_linter in l:lsp_linters
|
||||
call s:ExecuteGetCodeFix(l:lsp_linter, a:range, l:MenuCallback)
|
||||
for l:linter in l:linters
|
||||
call s:ExecuteGetCodeFix(l:linter, a:range, l:MenuCallback)
|
||||
endfor
|
||||
endfunction
|
||||
|
@ -824,6 +824,8 @@ endfunction
|
||||
" the current buffer. 1 will be returned if there's a potential source of
|
||||
" completion data ALE can use, and 0 will be returned otherwise.
|
||||
function! ale#completion#CanProvideCompletions() abort
|
||||
" NOTE: We can report that ALE can provide completions to Deoplete from
|
||||
" here, and we might ignore linters still below.
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
return 1
|
||||
@ -890,11 +892,9 @@ function! ale#completion#GetCompletions(...) abort
|
||||
|
||||
let l:started = 0
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
let l:started = 1
|
||||
endif
|
||||
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
|
||||
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
let l:started = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: This file implements debugging information for ALE
|
||||
|
||||
let g:ale_info_default_mode = get(g:, 'ale_info_default_mode', 'preview')
|
||||
|
||||
let s:global_variable_list = [
|
||||
\ 'ale_cache_executable_check_failures',
|
||||
\ 'ale_change_sign_column_color',
|
||||
@ -18,6 +20,7 @@ let s:global_variable_list = [
|
||||
\ 'ale_fix_on_save',
|
||||
\ 'ale_fixers',
|
||||
\ 'ale_history_enabled',
|
||||
\ 'ale_info_default_mode',
|
||||
\ 'ale_history_log_output',
|
||||
\ 'ale_keep_list_window_open',
|
||||
\ 'ale_lint_delay',
|
||||
@ -53,7 +56,6 @@ let s:global_variable_list = [
|
||||
\ 'ale_sign_style_warning',
|
||||
\ 'ale_sign_warning',
|
||||
\ 'ale_sign_highlight_linenrs',
|
||||
\ 'ale_statusline_format',
|
||||
\ 'ale_type_map',
|
||||
\ 'ale_use_neovim_diagnostics_api',
|
||||
\ 'ale_use_global_executables',
|
||||
@ -199,11 +201,42 @@ function! s:EchoLSPErrorMessages(all_linter_names) abort
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#Info() abort
|
||||
function! s:GetIgnoredLinters(buffer, enabled_linters) abort
|
||||
let l:filetype = &filetype
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
if (
|
||||
\ !empty(l:ignore_config)
|
||||
\ || l:disable_lsp is 1
|
||||
\ || l:disable_lsp is v:true
|
||||
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
|
||||
\)
|
||||
let l:non_ignored = ale#engine#ignore#Exclude(
|
||||
\ l:filetype,
|
||||
\ a:enabled_linters,
|
||||
\ l:ignore_config,
|
||||
\ l:disable_lsp,
|
||||
\)
|
||||
else
|
||||
let l:non_ignored = copy(a:enabled_linters)
|
||||
endif
|
||||
|
||||
call map(l:non_ignored, 'v:val.name')
|
||||
|
||||
return filter(
|
||||
\ copy(a:enabled_linters),
|
||||
\ 'index(l:non_ignored, v:val.name) < 0'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#Info(...) abort
|
||||
let l:options = (a:0 > 0) ? a:1 : {}
|
||||
let l:show_preview_info = get(l:options, 'preview')
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let l:filetype = &filetype
|
||||
|
||||
" We get the list of enabled linters for free by the above function.
|
||||
let l:enabled_linters = deepcopy(ale#linter#Get(l:filetype))
|
||||
|
||||
" But have to build the list of available linters ourselves.
|
||||
@ -227,13 +260,10 @@ function! ale#debugging#Info() abort
|
||||
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
|
||||
let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '')
|
||||
|
||||
let l:non_ignored_names = map(
|
||||
\ copy(ale#linter#RemoveIgnored(l:buffer, l:filetype, l:enabled_linters)),
|
||||
\ 'v:val[''name'']',
|
||||
\)
|
||||
let l:ignored_names = filter(
|
||||
\ copy(l:enabled_names),
|
||||
\ 'index(l:non_ignored_names, v:val) < 0'
|
||||
" Get the names of ignored linters.
|
||||
let l:ignored_names = map(
|
||||
\ s:GetIgnoredLinters(l:buffer, l:enabled_linters),
|
||||
\ 'v:val.name'
|
||||
\)
|
||||
|
||||
call s:Echo(' Current Filetype: ' . l:filetype)
|
||||
@ -241,13 +271,31 @@ function! ale#debugging#Info() abort
|
||||
call s:EchoLinterAliases(l:all_linters)
|
||||
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
|
||||
call s:Echo(' Ignored Linters: ' . string(l:ignored_names))
|
||||
call s:Echo(' Suggested Fixers: ' . l:fixers_string)
|
||||
call s:Echo(' Linter Variables:')
|
||||
call s:Echo('')
|
||||
call s:EchoLinterVariables(l:variable_list)
|
||||
call s:Echo(' Suggested Fixers:' . l:fixers_string)
|
||||
" We use this line with only a space to know where to end highlights.
|
||||
call s:Echo(' ')
|
||||
|
||||
" Only show Linter Variables directive if there are any.
|
||||
if !empty(l:variable_list)
|
||||
call s:Echo(' Linter Variables:')
|
||||
|
||||
if l:show_preview_info
|
||||
call s:Echo('" Press Space to read :help for a setting')
|
||||
endif
|
||||
|
||||
call s:EchoLinterVariables(l:variable_list)
|
||||
" We use this line with only a space to know where to end highlights.
|
||||
call s:Echo(' ')
|
||||
endif
|
||||
|
||||
call s:Echo(' Global Variables:')
|
||||
call s:Echo('')
|
||||
|
||||
if l:show_preview_info
|
||||
call s:Echo('" Press Space to read :help for a setting')
|
||||
endif
|
||||
|
||||
call s:EchoGlobalVariables()
|
||||
call s:Echo(' ')
|
||||
call s:EchoLSPErrorMessages(l:all_names)
|
||||
call s:Echo(' Command History:')
|
||||
call s:Echo('')
|
||||
@ -275,3 +323,41 @@ function! ale#debugging#InfoToFile(filename) abort
|
||||
call writefile(split(l:output, "\n"), l:expanded_filename)
|
||||
call s:Echo('ALEInfo written to ' . l:expanded_filename)
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToPreview() abort
|
||||
let l:output = execute('call ale#debugging#Info({''preview'': 1})')
|
||||
|
||||
call ale#preview#Show(split(l:output, "\n"), {
|
||||
\ 'filetype': 'ale-info',
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoCommand(...) abort
|
||||
if len(a:000) > 1
|
||||
" no-custom-checks
|
||||
echom 'Invalid ALEInfo arguments!'
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
" Get 'echo' from '-echo', if there's an argument.
|
||||
let l:mode = get(a:000, '')[1:]
|
||||
|
||||
if empty(l:mode)
|
||||
let l:mode = ale#Var(bufnr(''), 'info_default_mode')
|
||||
endif
|
||||
|
||||
if l:mode is# 'echo'
|
||||
call ale#debugging#Info()
|
||||
elseif l:mode is# 'clip' || l:mode is# 'clipboard'
|
||||
call ale#debugging#InfoToClipboard()
|
||||
else
|
||||
call ale#debugging#InfoToPreview()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToClipboardDeprecatedCommand() abort
|
||||
" no-custom-checks
|
||||
echom 'ALEInfoToClipboard is deprecated. Use ALEInfo -clipboard instead.'
|
||||
call ale#debugging#InfoToClipboard()
|
||||
endfunction
|
||||
|
@ -168,26 +168,20 @@ function! s:GoToLSPDefinition(linter, options, capability) abort
|
||||
endfunction
|
||||
|
||||
function! ale#definition#GoTo(options) abort
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'definition')
|
||||
endif
|
||||
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'definition')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#definition#GoToType(options) abort
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition')
|
||||
endif
|
||||
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition')
|
||||
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
|
||||
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'implementation')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
|
@ -253,7 +253,7 @@ function! ale#engine#SendResultsToNeovimDiagnostics(buffer, loclist) abort
|
||||
|
||||
" Keep the Lua surface area really small in the VimL part of ALE,
|
||||
" and just require the diagnostics.lua module on demand.
|
||||
let l:SendDiagnostics = luaeval('require("diagnostics").sendAleResultsToDiagnostics')
|
||||
let l:SendDiagnostics = luaeval('require("ale.diagnostics").sendAleResultsToDiagnostics')
|
||||
call l:SendDiagnostics(a:buffer, a:loclist)
|
||||
endfunction
|
||||
|
||||
|
@ -1,6 +1,26 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Code for ignoring linters. Only loaded and if configured.
|
||||
|
||||
" A map for remapping lspconfig server names to linter names or aliases in
|
||||
" ALE. We should change the names where they will conflict with names in ALE.
|
||||
"
|
||||
" Notes on names from nvim-lspconfig not included here.
|
||||
"
|
||||
" * 'rubocop' is run in a language server mode
|
||||
" * 'eslint' is run via 'vscode-eslint-language-server'
|
||||
let s:lspconfig_map = {
|
||||
\ 'als': 'adals',
|
||||
\ 'ansiblels': 'ansible-language-server',
|
||||
\ 'bicep': 'bicep_language_server',
|
||||
\ 'cmake': 'cmake_language_server',
|
||||
\ 'denols': 'deno',
|
||||
\ 'erlangls': 'erlang_ls',
|
||||
\ 'html': 'vscodehtml',
|
||||
\ 'ocamlls': 'ocaml-language-server',
|
||||
\ 'ols': 'odin-lsp',
|
||||
\ 'puppet': 'puppet_languageserver',
|
||||
\}
|
||||
|
||||
" Given a filetype and a configuration for ignoring linters, return a List of
|
||||
" Strings for linter names to ignore.
|
||||
function! ale#engine#ignore#GetList(filetype, config) abort
|
||||
@ -21,24 +41,51 @@ function! ale#engine#ignore#GetList(filetype, config) abort
|
||||
return []
|
||||
endfunction
|
||||
|
||||
" This function can be mocked in tests.
|
||||
function! ale#engine#ignore#GetLSPConfigNames() abort
|
||||
return luaeval('require ''ale.util''.configured_lspconfig_servers()')
|
||||
endfunction
|
||||
|
||||
function! s:GetMappedLSPConfigNames() abort
|
||||
" Check the lspconfig flag before calling luaeval.
|
||||
if !get(g:, 'lspconfig', 0)
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:lspconfig_servers = ale#engine#ignore#GetLSPConfigNames()
|
||||
|
||||
return map(
|
||||
\ !empty(l:lspconfig_servers) ? l:lspconfig_servers : [],
|
||||
\ {_, val -> get(s:lspconfig_map, val, val) }
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Given a List of linter descriptions, exclude the linters to be ignored.
|
||||
function! ale#engine#ignore#Exclude(filetype, all_linters, config, disable_lsp) abort
|
||||
let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config)
|
||||
|
||||
" If configured to automatically ignore otherwise configured LSP linter
|
||||
" names, add them to the names to remove. This could ignore linters
|
||||
" with matching names that are not marked as LSP linters.
|
||||
if a:disable_lsp is# 'auto'
|
||||
call extend(l:names_to_remove, s:GetMappedLSPConfigNames())
|
||||
endif
|
||||
|
||||
let l:ignore_all_lsps = a:disable_lsp is 1 || a:disable_lsp is v:true
|
||||
let l:filtered_linters = []
|
||||
|
||||
for l:linter in a:all_linters
|
||||
let l:name_list = [l:linter.name] + l:linter.aliases
|
||||
let l:should_include = 1
|
||||
let l:should_include = index(l:names_to_remove, l:linter.name) == -1
|
||||
let l:i = 0
|
||||
|
||||
for l:name in l:name_list
|
||||
if index(l:names_to_remove, l:name) >= 0
|
||||
let l:should_include = 0
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
while l:should_include && l:i < len(l:linter.aliases)
|
||||
let l:name = l:linter.aliases[l:i]
|
||||
let l:should_include = index(l:names_to_remove, l:name) == -1
|
||||
let l:i += 1
|
||||
endwhile
|
||||
|
||||
if a:disable_lsp && has_key(l:linter, 'lsp') && l:linter.lsp isnot# ''
|
||||
let l:should_include = 0
|
||||
if l:should_include && l:ignore_all_lsps
|
||||
let l:should_include = empty(get(l:linter, 'lsp'))
|
||||
endif
|
||||
|
||||
if l:should_include
|
||||
|
@ -92,6 +92,62 @@ function! ale#events#FileChangedEvent(buffer) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" A timer for emulating InsertLeave.
|
||||
"
|
||||
" We only need a single timer, and we'll lint the last buffer we entered
|
||||
" insert mode on.
|
||||
if !exists('s:insert_leave_timer')
|
||||
let s:insert_leave_timer = -1
|
||||
endif
|
||||
|
||||
function! ale#events#EmulateInsertLeave(buffer) abort
|
||||
if mode() is# 'n'
|
||||
call timer_stop(s:insert_leave_timer)
|
||||
call ale#Queue(0, '', a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#InsertEnterEvent(buffer) abort
|
||||
if g:ale_close_preview_on_insert && exists('*ale#preview#CloseIfTypeMatches')
|
||||
call ale#preview#CloseIfTypeMatches('ale-preview')
|
||||
endif
|
||||
|
||||
" Start a repeating timer if the use might not trigger InsertLeave, so we
|
||||
" can emulate its behavior.
|
||||
if ale#Var(a:buffer, 'lint_on_insert_leave')
|
||||
\&& maparg("\<C-c>", 'i') isnot# '<Esc>'
|
||||
call timer_stop(s:insert_leave_timer)
|
||||
let s:insert_leave_timer = timer_start(
|
||||
\ 100,
|
||||
\ {-> ale#events#EmulateInsertLeave(a:buffer) },
|
||||
\ {'repeat': -1}
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#InsertLeaveEvent(buffer) abort
|
||||
if ale#Var(a:buffer, 'lint_on_insert_leave')
|
||||
" Kill the InsertLeave emulation if the event fired.
|
||||
call timer_stop(s:insert_leave_timer)
|
||||
call ale#Queue(0)
|
||||
endif
|
||||
|
||||
" 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.
|
||||
"
|
||||
" We don't echo this message in emulated insert leave mode, as the user
|
||||
" may want less work to happen on pressing <C-c> versus <Esc>
|
||||
if exists('*ale#engine#Cleanup')
|
||||
call ale#cursor#EchoCursorWarning()
|
||||
|
||||
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
|
||||
" Show a virtualtext message if enabled.
|
||||
call ale#virtualtext#ShowCursorWarning()
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#Init() 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
|
||||
@ -127,33 +183,40 @@ function! ale#events#Init() abort
|
||||
\)
|
||||
endif
|
||||
|
||||
if g:ale_lint_on_insert_leave
|
||||
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif
|
||||
" Add an InsertEnter event if we need to close the preview window
|
||||
" on entering insert mode, or if we want to run ALE on leaving
|
||||
" insert mode and <C-c> is not the same as <Esc>.
|
||||
"
|
||||
" We will emulate leaving insert mode for users that might not
|
||||
" trigger InsertLeave.
|
||||
if g:ale_close_preview_on_insert
|
||||
\|| (g:ale_lint_on_insert_leave && maparg("\<C-c>", 'i') isnot# '<Esc>')
|
||||
autocmd InsertEnter * call ale#events#InsertEnterEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
|
||||
let l:add_insert_leave_event = g:ale_lint_on_insert_leave
|
||||
|
||||
if g:ale_echo_cursor || g:ale_cursor_detail
|
||||
" We need to make the message display on InsertLeave
|
||||
let l:add_insert_leave_event = 1
|
||||
|
||||
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif
|
||||
" 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 * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarning() | endif
|
||||
endif
|
||||
|
||||
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
|
||||
" We need to make the message display on InsertLeave
|
||||
let l:add_insert_leave_event = 1
|
||||
|
||||
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarningWithDelay() | endif
|
||||
" 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 * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarning() | endif
|
||||
endif
|
||||
|
||||
if l:add_insert_leave_event
|
||||
autocmd InsertLeave * call ale#events#InsertLeaveEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
|
||||
if g:ale_hover_cursor
|
||||
autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif
|
||||
endif
|
||||
|
||||
if g:ale_close_preview_on_insert
|
||||
autocmd InsertEnter * if exists('*ale#preview#CloseIfTypeMatches') | call ale#preview#CloseIfTypeMatches('ale-preview') | endif
|
||||
endif
|
||||
endif
|
||||
augroup END
|
||||
|
||||
|
@ -94,9 +94,10 @@ function! s:ExecuteFileRename(linter, options) abort
|
||||
endfunction
|
||||
|
||||
function! ale#filerename#Execute() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:lsp_linters = []
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
|
||||
if l:linter.lsp is# 'tsserver'
|
||||
call add(l:lsp_linters, l:linter)
|
||||
endif
|
||||
@ -108,7 +109,6 @@ function! ale#filerename#Execute() abort
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let l:old_name = expand('#' . l:buffer . ':p')
|
||||
let l:new_name = ale#util#Input('New file name: ', l:old_name, 'file')
|
||||
|
||||
|
@ -32,7 +32,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
catch /E21/
|
||||
catch /E21\|E5555/
|
||||
" If we cannot modify the buffer now, try again later.
|
||||
let g:ale_fix_buffer_data[a:buffer] = l:data
|
||||
|
||||
|
@ -286,6 +286,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['fish'],
|
||||
\ 'description': 'Format fish scripts using fish_indent.',
|
||||
\ },
|
||||
\ 'forge': {
|
||||
\ 'function': 'ale#fixers#forge#Fix',
|
||||
\ 'suggested_filetypes': ['solidity'],
|
||||
\ 'description': 'Fix Solidity files with forge fmt.',
|
||||
\ },
|
||||
\ 'gofmt': {
|
||||
\ 'function': 'ale#fixers#gofmt#Fix',
|
||||
\ 'suggested_filetypes': ['go'],
|
||||
@ -606,6 +611,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix python files with ruff.',
|
||||
\ },
|
||||
\ 'ruff_format': {
|
||||
\ 'function': 'ale#fixers#ruff_format#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix python files with the ruff formatter.',
|
||||
\ },
|
||||
\ 'pycln': {
|
||||
\ 'function': 'ale#fixers#pycln#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
@ -625,7 +635,12 @@ let s:default_registry = {
|
||||
\ 'function': 'ale#fixers#erbformatter#Fix',
|
||||
\ 'suggested_filetypes': ['eruby'],
|
||||
\ 'description': 'Apply erb-formatter -w to eruby/erb files.',
|
||||
\ }
|
||||
\ },
|
||||
\ 'nickel_format': {
|
||||
\ 'function': 'ale#fixers#nickel_format#Fix',
|
||||
\ 'suggested_filetypes': ['nickel'],
|
||||
\ 'description': 'Fix nickel files with nickel format',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
|
11
sources_non_forked/ale/autoload/ale/fixers/forge.vim
Normal file
11
sources_non_forked/ale/autoload/ale/fixers/forge.vim
Normal file
@ -0,0 +1,11 @@
|
||||
call ale#Set('solidity_forge_executable', 'forge')
|
||||
|
||||
function! ale#fixers#forge#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'solidity_forge_executable')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' fmt %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
16
sources_non_forked/ale/autoload/ale/fixers/nickel_format.vim
Normal file
16
sources_non_forked/ale/autoload/ale/fixers/nickel_format.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: Yining <zhang.yining@gmail.com>
|
||||
" Description: nickel format as ALE fixer for Nickel files
|
||||
|
||||
call ale#Set('nickel_nickel_format_executable', 'nickel')
|
||||
call ale#Set('nickel_nickel_format_options', '')
|
||||
|
||||
function! ale#fixers#nickel_format#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'nickel_nickel_format_executable')
|
||||
let l:options = ale#Var(a:buffer, 'nickel_nickel_format_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' format'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
||||
|
72
sources_non_forked/ale/autoload/ale/fixers/ruff_format.vim
Normal file
72
sources_non_forked/ale/autoload/ale/fixers/ruff_format.vim
Normal file
@ -0,0 +1,72 @@
|
||||
" Author: Yining <zhang.yining@gmail.com>, Joseph Henrich <crimsonknave@gmail.com>
|
||||
" Description: ruff formatter as ALE fixer for python files
|
||||
|
||||
call ale#Set('python_ruff_format_executable', 'ruff')
|
||||
call ale#Set('python_ruff_format_options', '')
|
||||
call ale#Set('python_ruff_format_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_ruff_format_change_directory', 1)
|
||||
call ale#Set('python_ruff_format_auto_pipenv', 0)
|
||||
call ale#Set('python_ruff_format_auto_poetry', 0)
|
||||
|
||||
function! ale#fixers#ruff_format#GetCwd(buffer) abort
|
||||
if ale#Var(a:buffer, 'python_ruff_format_change_directory')
|
||||
" Run from project root if found, else from buffer dir.
|
||||
let l:project_root = ale#python#FindProjectRoot(a:buffer)
|
||||
|
||||
return !empty(l:project_root) ? l:project_root : '%s:h'
|
||||
endif
|
||||
|
||||
return '%s:h'
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#ruff_format#GetExecutable(buffer) abort
|
||||
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_ruff_format_auto_pipenv'))
|
||||
\ && ale#python#PipenvPresent(a:buffer)
|
||||
return 'pipenv'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_ruff_format_auto_poetry'))
|
||||
\ && ale#python#PoetryPresent(a:buffer)
|
||||
return 'poetry'
|
||||
endif
|
||||
|
||||
return ale#python#FindExecutable(a:buffer, 'python_ruff_format', ['ruff'])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#ruff_format#GetCommand(buffer) abort
|
||||
let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer)
|
||||
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
|
||||
\ ? ' run ruff'
|
||||
\ : ''
|
||||
|
||||
return ale#Escape(l:executable) . l:exec_args
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#ruff_format#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer)
|
||||
let l:cmd = [ale#Escape(l:executable)]
|
||||
|
||||
if l:executable =~? 'pipenv\|poetry$'
|
||||
call extend(l:cmd, ['run', 'ruff'])
|
||||
endif
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_ruff_format_options')
|
||||
|
||||
" when --stdin-filename present, ruff will use it for proj root resolution
|
||||
" https://github.com/charliermarsh/ruff/pull/1281
|
||||
let l:fname = expand('#' . a:buffer . '...')
|
||||
call add(l:cmd, 'format')
|
||||
|
||||
if !empty(l:options)
|
||||
call add(l:cmd, l:options)
|
||||
endif
|
||||
|
||||
call add(l:cmd, '--stdin-filename '.ale#Escape(ale#path#Simplify(l:fname)))
|
||||
|
||||
call add(l:cmd, '-')
|
||||
|
||||
return {
|
||||
\ 'cwd': ale#fixers#ruff_format#GetCwd(a:buffer),
|
||||
\ 'command': join(l:cmd, ' '),
|
||||
\}
|
||||
endfunction
|
@ -1,36 +0,0 @@
|
||||
function! ale#handlers#actionlint#GetCommand(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'yaml_actionlint_options')
|
||||
|
||||
" automatically add --no-color option if not defined
|
||||
if l:options !~# '--no-color'
|
||||
let l:options .= ' --no-color'
|
||||
endif
|
||||
|
||||
" automatically add --oneline option if not defined
|
||||
if l:options !~# '--oneline'
|
||||
let l:options .= ' --oneline'
|
||||
endif
|
||||
|
||||
return '%e ' . l:options . ' %t'
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#actionlint#Handle(buffer, lines) abort
|
||||
" Matches patterns line the following:
|
||||
".github/workflows/main.yml:19:0: could not parse as YAML: yaml: line 19: mapping values are not allowed in this context [yaml-syntax]
|
||||
let l:pattern = '\v^.*:(\d+):(\d+): (.+) \[(.+)\]$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
let l:item = {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[3],
|
||||
\ 'code': l:match[4],
|
||||
\ 'type': 'E',
|
||||
\}
|
||||
|
||||
call add(l:output, l:item)
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
41
sources_non_forked/ale/autoload/ale/handlers/cairo.vim
Normal file
41
sources_non_forked/ale/autoload/ale/handlers/cairo.vim
Normal file
@ -0,0 +1,41 @@
|
||||
" Author: 0xhyoga <0xhyoga@gmx.com>,
|
||||
" Description: This file implements handlers specific to Cairo
|
||||
"
|
||||
function! ale#handlers#cairo#HandleCairoErrors(buffer, lines) abort
|
||||
" Matches patterns like the following:
|
||||
" Error: Expected ';' but got '('
|
||||
" --> /path/to/file/file.cairo:1:10:)
|
||||
let l:pattern = '\v(error|warning): (.*)$'
|
||||
let l:line_and_column_pattern = '\v\.cairo:(\d+):(\d+)'
|
||||
let l:exclude_pattern = '\vcould not compile.*'
|
||||
let l:output = []
|
||||
|
||||
for l:line in a:lines
|
||||
let l:match = matchlist(l:line, l:pattern)
|
||||
|
||||
if len(l:match) == 0
|
||||
let l:match = matchlist(l:line, l:line_and_column_pattern)
|
||||
|
||||
if len(l:match) > 0
|
||||
let l:index = len(l:output) - 1
|
||||
let l:output[l:index]['lnum'] = l:match[1] + 0
|
||||
let l:output[l:index]['col'] = l:match[2] + 0
|
||||
endif
|
||||
else
|
||||
let l:text = l:match[2]
|
||||
|
||||
if l:text !~# l:exclude_pattern
|
||||
let l:isError = l:match[1] is? 'Error'
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': 0,
|
||||
\ 'col': 0,
|
||||
\ 'text': l:text,
|
||||
\ 'type': l:isError ? 'E' : 'W',
|
||||
\})
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
@ -4,7 +4,7 @@
|
||||
|
||||
call ale#Set('deno_executable', 'deno')
|
||||
call ale#Set('deno_unstable', 0)
|
||||
call ale#Set('deno_importMap', 'import_map.json')
|
||||
call ale#Set('deno_import_map', 'import_map.json')
|
||||
call ale#Set('deno_lsp_project_root', '')
|
||||
|
||||
function! ale#handlers#deno#GetExecutable(buffer) abort
|
||||
@ -68,8 +68,19 @@ function! ale#handlers#deno#GetInitializationOptions(buffer) abort
|
||||
let l:options.unstable = v:true
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'deno_importMap') isnot# ''
|
||||
let l:options.importMap = ale#path#FindNearestFile(a:buffer, ale#Var(a:buffer, 'deno_importMap'))
|
||||
" Look for a value set using the historical option name.
|
||||
let l:import_map = getbufvar(
|
||||
\ a:buffer,
|
||||
\ 'ale_deno_importMap',
|
||||
\ get(g:, 'ale_deno_importMap', '')
|
||||
\)
|
||||
|
||||
if empty(l:import_map)
|
||||
let l:import_map = ale#Var(a:buffer, 'deno_import_map')
|
||||
endif
|
||||
|
||||
if !empty(l:import_map)
|
||||
let l:options.importMap = ale#path#FindNearestFile(a:buffer, l:import_map)
|
||||
endif
|
||||
|
||||
return l:options
|
||||
|
@ -61,7 +61,8 @@ endfunction
|
||||
" Define the hdl_checker linter for a given filetype.
|
||||
function! ale#handlers#hdl_checker#DefineLinter(filetype) abort
|
||||
call ale#linter#Define(a:filetype, {
|
||||
\ 'name': 'hdl-checker',
|
||||
\ 'name': 'hdl_checker',
|
||||
\ 'aliases': ['hdl-checker'],
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'language': a:filetype,
|
||||
\ 'executable': function('ale#handlers#hdl_checker#GetExecutable'),
|
||||
@ -70,4 +71,3 @@ function! ale#handlers#hdl_checker#DefineLinter(filetype) abort
|
||||
\ 'initialization_options': function('ale#handlers#hdl_checker#GetInitOptions'),
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
|
@ -102,7 +102,7 @@ function! ale#handlers#shellcheck#DefineLinter(filetype) abort
|
||||
" This global variable can be set with a string of comma-separated error
|
||||
" codes to exclude from shellcheck. For example:
|
||||
" let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004'
|
||||
call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', ''))
|
||||
call ale#Set('sh_shellcheck_exclusions', '')
|
||||
call ale#Set('sh_shellcheck_executable', 'shellcheck')
|
||||
call ale#Set('sh_shellcheck_dialect', 'auto')
|
||||
call ale#Set('sh_shellcheck_options', '')
|
||||
|
@ -1,98 +0,0 @@
|
||||
" Author: Henrique Barcelos <@hbarcelos>
|
||||
" Description: Functions for working with local solhint for checking *.sol files.
|
||||
|
||||
let s:executables = [
|
||||
\ 'node_modules/.bin/solhint',
|
||||
\ 'node_modules/solhint/solhint.js',
|
||||
\ 'solhint',
|
||||
\]
|
||||
|
||||
let s:sep = has('win32') ? '\' : '/'
|
||||
|
||||
call ale#Set('solidity_solhint_options', '')
|
||||
call ale#Set('solidity_solhint_executable', 'solhint')
|
||||
call ale#Set('solidity_solhint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#handlers#solhint#Handle(buffer, lines) abort
|
||||
" Matches patterns like the following:
|
||||
" /path/to/file/file.sol: line 1, col 10, Error - 'addOne' is defined but never used. (no-unused-vars)
|
||||
let l:output = []
|
||||
|
||||
let l:lint_pattern = '\v^[^:]+: line (\d+), col (\d+), (Error|Warning) - (.*) \((.*)\)$'
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:lint_pattern)
|
||||
let l:isError = l:match[3] is? 'error'
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[4],
|
||||
\ 'code': l:match[5],
|
||||
\ 'type': l:isError ? 'E' : 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
let l:syntax_pattern = '\v^[^:]+: line (\d+), col (\d+), (Error|Warning) - (Parse error): (.*)$'
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:syntax_pattern)
|
||||
let l:isError = l:match[3] is? 'error'
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[5],
|
||||
\ 'code': l:match[4],
|
||||
\ 'type': l:isError ? 'E' : 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#solhint#FindConfig(buffer) abort
|
||||
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
|
||||
for l:basename in [
|
||||
\ '.solhintrc.js',
|
||||
\ '.solhintrc.json',
|
||||
\ '.solhintrc',
|
||||
\]
|
||||
let l:config = ale#path#Simplify(join([l:path, l:basename], s:sep))
|
||||
|
||||
if filereadable(l:config)
|
||||
return l:config
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return ale#path#FindNearestFile(a:buffer, 'package.json')
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#solhint#GetExecutable(buffer) abort
|
||||
return ale#path#FindExecutable(a:buffer, 'solidity_solhint', s:executables)
|
||||
endfunction
|
||||
|
||||
" Given a buffer, return an appropriate working directory for solhint.
|
||||
function! ale#handlers#solhint#GetCwd(buffer) abort
|
||||
" If solhint is installed in a directory which contains the buffer, assume
|
||||
" it is the solhint project root. Otherwise, use nearest node_modules.
|
||||
" Note: If node_modules not present yet, can't load local deps anyway.
|
||||
let l:executable = ale#path#FindNearestExecutable(a:buffer, s:executables)
|
||||
|
||||
if !empty(l:executable)
|
||||
let l:nmi = strridx(l:executable, 'node_modules')
|
||||
let l:project_dir = l:executable[0:l:nmi - 2]
|
||||
else
|
||||
let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules')
|
||||
let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : ''
|
||||
endif
|
||||
|
||||
return !empty(l:project_dir) ? l:project_dir : ''
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#solhint#GetCommand(buffer) abort
|
||||
let l:executable = ale#handlers#solhint#GetExecutable(a:buffer)
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'solidity_solhint_options')
|
||||
|
||||
return ale#node#Executable(a:buffer, l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --formatter compact %s'
|
||||
endfunction
|
@ -117,7 +117,7 @@ function! ale#hover#ParseLSPResult(contents) abort
|
||||
for l:line in split(l:item, "\n")
|
||||
if l:fence_language is v:null
|
||||
" Look for the start of a code fence. (```python, etc.)
|
||||
let l:match = matchlist(l:line, '^```\(.*\)$')
|
||||
let l:match = matchlist(l:line, '^``` *\([^ ]\+\) *$')
|
||||
|
||||
if !empty(l:match)
|
||||
let l:fence_language = l:match[1]
|
||||
@ -329,10 +329,9 @@ function! ale#hover#Show(buffer, line, col, opt) abort
|
||||
let l:show_documentation = get(a:opt, 'show_documentation', 0)
|
||||
let l:Callback = function('s:OnReady', [a:line, a:col, a:opt])
|
||||
|
||||
for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
||||
for l:linter in ale#lsp_linter#GetEnabled(a:buffer)
|
||||
" Only tsserver supports documentation requests at the moment.
|
||||
if !empty(l:linter.lsp)
|
||||
\&& (!l:show_documentation || l:linter.lsp is# 'tsserver')
|
||||
if !l:show_documentation || l:linter.lsp is# 'tsserver'
|
||||
call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
endfor
|
||||
|
@ -53,7 +53,7 @@ let s:default_ale_linters = {
|
||||
\ 'perl': ['perlcritic'],
|
||||
\ 'perl6': [],
|
||||
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'],
|
||||
\ 'rust': ['cargo', 'rls'],
|
||||
\ 'rust': ['analyzer', 'cargo'],
|
||||
\ 'spec': [],
|
||||
\ 'text': [],
|
||||
\ 'vader': ['vimls'],
|
||||
@ -417,16 +417,6 @@ function! ale#linter#Get(original_filetypes) abort
|
||||
return reverse(l:combined_linters)
|
||||
endfunction
|
||||
|
||||
function! ale#linter#RemoveIgnored(buffer, filetype, linters) abort
|
||||
" Apply ignore lists for linters only if needed.
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
return !empty(l:ignore_config) || l:disable_lsp
|
||||
\ ? ale#engine#ignore#Exclude(a:filetype, a:linters, l:ignore_config, l:disable_lsp)
|
||||
\ : a:linters
|
||||
endfunction
|
||||
|
||||
" Given a buffer and linter, get the executable String for the linter.
|
||||
function! ale#linter#GetExecutable(buffer, linter) abort
|
||||
let l:Executable = a:linter.executable
|
||||
|
@ -1,9 +1,16 @@
|
||||
" Author: w0rp <dev@w0rp.com>
|
||||
" Description: Functions for resetting LSP servers.
|
||||
|
||||
function! s:Message(message) abort
|
||||
call ale#util#Execute('echom ' . string(a:message))
|
||||
endfunction
|
||||
|
||||
" Stop all LSPs and remove all of the data for them.
|
||||
function! ale#lsp#reset#StopAllLSPs() abort
|
||||
call ale#lsp#StopAll()
|
||||
|
||||
if exists('*ale#definition#ClearLSPData')
|
||||
" Clear the mapping for connections, etc.
|
||||
" Clear the go to definition mapping for everything.
|
||||
call ale#definition#ClearLSPData()
|
||||
endif
|
||||
|
||||
@ -15,6 +22,8 @@ function! ale#lsp#reset#StopAllLSPs() abort
|
||||
for l:buffer_string in keys(g:ale_buffer_info)
|
||||
let l:buffer = str2nr(l:buffer_string)
|
||||
|
||||
" Non-ignored and disabled linters are included here so we can
|
||||
" clear results for them after we ignore or disable them.
|
||||
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||
if !empty(l:linter.lsp)
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [], 0)
|
||||
@ -23,3 +32,61 @@ function! ale#lsp#reset#StopAllLSPs() abort
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#reset#Complete(arg, line, pos) abort
|
||||
let l:linter_map = ale#lsp_linter#GetLSPLinterMap()
|
||||
let l:candidates = map(values(l:linter_map), {_, linter -> linter.name})
|
||||
call uniq(sort(l:candidates))
|
||||
call filter(l:candidates, {_, name -> name =~? a:arg})
|
||||
|
||||
return l:candidates
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#reset#StopLSP(name, bang) abort
|
||||
let l:linter_map = ale#lsp_linter#GetLSPLinterMap()
|
||||
let l:matched = filter(
|
||||
\ items(l:linter_map),
|
||||
\ {_, item -> item[1].name is# a:name}
|
||||
\)
|
||||
|
||||
if empty(l:matched)
|
||||
if a:bang isnot# '!'
|
||||
call s:Message('No running language server with name: ' . a:name)
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
" Stop LSP connections first.
|
||||
for [l:conn_id, l:linter] in l:matched
|
||||
call ale#lsp#Stop(l:conn_id)
|
||||
endfor
|
||||
|
||||
if exists('*ale#definition#ClearLSPData')
|
||||
" Clear the go to definition mapping for everything.
|
||||
call ale#definition#ClearLSPData()
|
||||
endif
|
||||
|
||||
" Remove connections from the lsp_linter map.
|
||||
for [l:conn_id, l:linter] in l:matched
|
||||
call remove(l:linter_map, l:conn_id)
|
||||
endfor
|
||||
|
||||
" Remove the problems for the LSP linters in every buffer.
|
||||
for [l:buffer_string, l:info] in items(g:ale_buffer_info)
|
||||
let l:buffer = str2nr(l:buffer_string)
|
||||
let l:should_clear_buffer = 0
|
||||
|
||||
for l:item in l:info.loclist
|
||||
if l:item.linter_name is# a:name
|
||||
let l:should_clear_buffer = 1
|
||||
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
if l:should_clear_buffer
|
||||
call ale#engine#HandleLoclist(a:name, l:buffer, [], 0)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
@ -8,13 +8,9 @@ if !has_key(s:, 'lsp_linter_map')
|
||||
let s:lsp_linter_map = {}
|
||||
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.
|
||||
@ -27,28 +23,67 @@ 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.
|
||||
if ale#Var(a:buffer, 'disable_lsp')
|
||||
return 1
|
||||
endif
|
||||
|
||||
let l:config = ale#Var(a:buffer, 'linters_ignore')
|
||||
|
||||
" Don't load code for ignoring diagnostics if there's nothing to ignore.
|
||||
if empty(l:config)
|
||||
return 0
|
||||
endif
|
||||
|
||||
" Get all enabled LSP linters.
|
||||
" This list still includes linters ignored with `ale_linters_ignore`.
|
||||
"
|
||||
" `ale_linters_ignore` is designed to allow language servers to be used for
|
||||
" their functionality while ignoring the diagnostics they return.
|
||||
function! ale#lsp_linter#GetEnabled(buffer) abort
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
let l:ignore_list = ale#engine#ignore#GetList(l:filetype, l:config)
|
||||
" Only LSP linters are included here.
|
||||
let l:linters = filter(ale#linter#Get(l:filetype), '!empty(v:val.lsp)')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
return index(l:ignore_list, a:linter_name) >= 0
|
||||
" Only load code for ignoring linters if we need it.
|
||||
if (
|
||||
\ l:disable_lsp is 1
|
||||
\ || l:disable_lsp is v:true
|
||||
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
|
||||
\)
|
||||
let l:linters = ale#engine#ignore#Exclude(
|
||||
\ l:filetype,
|
||||
\ l:linters,
|
||||
\ [],
|
||||
\ l:disable_lsp,
|
||||
\)
|
||||
endif
|
||||
|
||||
return l:linters
|
||||
endfunction
|
||||
|
||||
" Check if diagnostics for a particular linter should be ignored.
|
||||
function! s:ShouldIgnoreDiagnostics(buffer, linter) abort
|
||||
let l:config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
" Only load code for ignoring linters if we need it.
|
||||
if (
|
||||
\ !empty(l:config)
|
||||
\ || l:disable_lsp is 1
|
||||
\ || l:disable_lsp is v:true
|
||||
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
|
||||
\)
|
||||
" Re-use the ignore implementation just for this linter.
|
||||
return empty(
|
||||
\ ale#engine#ignore#Exclude(
|
||||
\ getbufvar(a:buffer, '&filetype'),
|
||||
\ [a:linter],
|
||||
\ l:config,
|
||||
\ l:disable_lsp,
|
||||
\ )
|
||||
\)
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
||||
let l:linter_name = s:lsp_linter_map[a:conn_id]
|
||||
let l:linter = get(s:lsp_linter_map, a:conn_id)
|
||||
|
||||
if empty(l:linter)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:filename = ale#util#ToResource(a:response.params.uri)
|
||||
let l:escaped_name = escape(
|
||||
\ fnameescape(l:filename),
|
||||
@ -61,17 +96,22 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
|
||||
return
|
||||
endif
|
||||
|
||||
if s:ShouldIgnore(l:buffer, l:linter_name)
|
||||
if s:ShouldIgnoreDiagnostics(l:buffer, l:linter)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
let l:linter_name = 'tsserver'
|
||||
" Re-create a fake linter object for tsserver.
|
||||
let l:linter = {
|
||||
\ 'name': 'tsserver',
|
||||
\ 'aliases': [],
|
||||
\ 'lsp': 'tsserver',
|
||||
\}
|
||||
let l:escaped_name = escape(
|
||||
\ fnameescape(a:response.body.file),
|
||||
\ has('win32') ? '^' : '^,}]'
|
||||
@ -83,9 +123,9 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#engine#MarkLinterInactive(l:info, l:linter_name)
|
||||
call ale#engine#MarkLinterInactive(l:info, l:linter.name)
|
||||
|
||||
if s:ShouldIgnore(l:buffer, l:linter_name)
|
||||
if s:ShouldIgnoreDiagnostics(l:buffer, l:linter)
|
||||
return
|
||||
endif
|
||||
|
||||
@ -123,15 +163,15 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
\ + get(l:info, 'suggestion_loclist', [])
|
||||
\ + get(l:info, 'syntax_loclist', [])
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPErrorMessage(linter_name, response) abort
|
||||
function! s:HandleLSPErrorMessage(linter, response) abort
|
||||
if !g:ale_history_enabled || !g:ale_history_log_output
|
||||
return
|
||||
endif
|
||||
|
||||
if empty(a:linter_name)
|
||||
if empty(a:linter)
|
||||
return
|
||||
endif
|
||||
|
||||
@ -141,7 +181,7 @@ function! s:HandleLSPErrorMessage(linter_name, response) abort
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#lsp_linter#AddErrorMessage(a:linter_name, l:message)
|
||||
call ale#lsp_linter#AddErrorMessage(a:linter.name, l:message)
|
||||
endfunction
|
||||
|
||||
function! ale#lsp_linter#AddErrorMessage(linter_name, message) abort
|
||||
@ -160,14 +200,14 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
|
||||
let l:method = get(a:response, 'method', '')
|
||||
|
||||
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
|
||||
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
|
||||
let l:linter = get(s:lsp_linter_map, a:conn_id, {})
|
||||
|
||||
call s:HandleLSPErrorMessage(l:linter_name, a:response)
|
||||
call s:HandleLSPErrorMessage(l:linter, a:response)
|
||||
elseif l:method is# 'textDocument/publishDiagnostics'
|
||||
call s:HandleLSPDiagnostics(a:conn_id, a:response)
|
||||
elseif l:method is# 'window/showMessage'
|
||||
call ale#lsp_window#HandleShowMessage(
|
||||
\ s:lsp_linter_map[a:conn_id],
|
||||
\ s:lsp_linter_map[a:conn_id].name,
|
||||
\ g:ale_lsp_show_message_format,
|
||||
\ a:response.params
|
||||
\)
|
||||
@ -221,11 +261,7 @@ function! ale#lsp_linter#GetConfig(buffer, linter) abort
|
||||
endfunction
|
||||
|
||||
function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
|
||||
let l:buffer_ale_root = getbufvar(
|
||||
\ a:buffer,
|
||||
\ 'ale_root',
|
||||
\ getbufvar(a:buffer, 'ale_lsp_root', {})
|
||||
\)
|
||||
let l:buffer_ale_root = getbufvar(a:buffer, 'ale_root', {})
|
||||
|
||||
if type(l:buffer_ale_root) is v:t_string
|
||||
return l:buffer_ale_root
|
||||
@ -242,15 +278,9 @@ function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:global_root = g:ale_root
|
||||
|
||||
if empty(g:ale_root) && exists('g:ale_lsp_root')
|
||||
let l:global_root = g:ale_lsp_root
|
||||
endif
|
||||
|
||||
" Try to get a global setting for the root
|
||||
if has_key(l:global_root, a:linter.name)
|
||||
let l:Root = l:global_root[a:linter.name]
|
||||
if has_key(g:ale_root, a:linter.name)
|
||||
let l:Root = g:ale_root[a:linter.name]
|
||||
|
||||
if type(l:Root) is v:t_func
|
||||
return l:Root(a:buffer)
|
||||
@ -472,7 +502,7 @@ function! s:CheckWithLSP(linter, details) abort
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
" Remember the linter this connection is for.
|
||||
let s:lsp_linter_map[l:id] = a:linter.name
|
||||
let s:lsp_linter_map[l:id] = a:linter
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
|
||||
@ -501,9 +531,14 @@ endfunction
|
||||
|
||||
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:custom_handlers_map, a:response.id)
|
||||
let l:Handler = remove(s:custom_handlers_map, a:response.id)
|
||||
call l:Handler(a:response)
|
||||
" Get the custom handlers Dictionary from the linter map.
|
||||
let l:linter = get(s:lsp_linter_map, a:conn_id, {})
|
||||
let l:custom_handlers = get(l:linter, 'custom_handlers', {})
|
||||
|
||||
if has_key(l:custom_handlers, a:response.id)
|
||||
let l:Handler = remove(l:custom_handlers, a:response.id)
|
||||
call l:Handler(a:response)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -514,7 +549,17 @@ function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
|
||||
if l:request_id > 0 && has_key(a:args, 'handler')
|
||||
let l:Callback = function('s:HandleLSPResponseToCustomRequests')
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
let s:custom_handlers_map[l:request_id] = a:args.handler
|
||||
|
||||
" Remember the linter this connection is for.
|
||||
let s:lsp_linter_map[l:id] = a:linter
|
||||
|
||||
" Add custom_handlers to the linter Dictionary.
|
||||
if !has_key(a:linter, 'custom_handlers')
|
||||
let a:linter.custom_handlers = {}
|
||||
endif
|
||||
|
||||
" Put the handler function in the map to call later.
|
||||
let a:linter.custom_handlers[l:request_id] = a:args.handler
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -19,7 +19,7 @@ function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
|
||||
\ },
|
||||
\ {
|
||||
\ 'conn_id': a:conn_id,
|
||||
\ 'should_save': !&hidden,
|
||||
\ 'should_save': g:ale_save_hidden || !&hidden,
|
||||
\ },
|
||||
\)
|
||||
endfunction
|
||||
@ -57,9 +57,7 @@ function! s:OrganizeImports(linter) abort
|
||||
endfunction
|
||||
|
||||
function! ale#organize_imports#Execute() abort
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:OrganizeImports(l:linter)
|
||||
endif
|
||||
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
call s:OrganizeImports(l:linter)
|
||||
endfor
|
||||
endfunction
|
||||
|
@ -7,14 +7,17 @@ call ale#Set('python_auto_poetry', '0')
|
||||
let s:sep = has('win32') ? '\' : '/'
|
||||
" bin is used for Unix virtualenv directories, and Scripts is for Windows.
|
||||
let s:bin_dir = has('unix') ? 'bin' : 'Scripts'
|
||||
" The default virtualenv directory names are ordered from the likely most
|
||||
" common names down to the least common. `.env` might be more common, but it's
|
||||
" also likely to conflict with a `.env` file for environment variables, so we
|
||||
" search for it last. (People really shouldn't use that name.)
|
||||
let g:ale_virtualenv_dir_names = get(g:, 'ale_virtualenv_dir_names', [
|
||||
\ '.env',
|
||||
\ '.venv',
|
||||
\ 'env',
|
||||
\ 've-py3',
|
||||
\ 've',
|
||||
\ 'virtualenv',
|
||||
\ 'venv',
|
||||
\ 'virtualenv',
|
||||
\ '.env',
|
||||
\])
|
||||
|
||||
function! ale#python#FindProjectRootIni(buffer) abort
|
||||
|
@ -179,9 +179,7 @@ function! ale#references#Find(...) abort
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
let l:Callback = function('s:OnReady', [l:line, l:column, l:options])
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
endfor
|
||||
endfunction
|
||||
|
@ -85,7 +85,7 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort
|
||||
\ },
|
||||
\ {
|
||||
\ 'conn_id': a:conn_id,
|
||||
\ 'should_save': !&hidden,
|
||||
\ 'should_save': g:ale_save_hidden || !&hidden,
|
||||
\ },
|
||||
\)
|
||||
endfunction
|
||||
@ -118,7 +118,7 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
|
||||
\ },
|
||||
\ {
|
||||
\ 'conn_id': a:conn_id,
|
||||
\ 'should_save': !&hidden,
|
||||
\ 'should_save': g:ale_save_hidden || !&hidden,
|
||||
\ },
|
||||
\)
|
||||
endif
|
||||
@ -178,15 +178,9 @@ function! s:ExecuteRename(linter, options) abort
|
||||
endfunction
|
||||
|
||||
function! ale#rename#Execute() abort
|
||||
let l:lsp_linters = []
|
||||
let l:linters = ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call add(l:lsp_linters, l:linter)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if empty(l:lsp_linters)
|
||||
if empty(l:linters)
|
||||
call s:message('No active LSPs')
|
||||
|
||||
return
|
||||
@ -201,8 +195,8 @@ function! ale#rename#Execute() abort
|
||||
return
|
||||
endif
|
||||
|
||||
for l:lsp_linter in l:lsp_linters
|
||||
call s:ExecuteRename(l:lsp_linter, {
|
||||
for l:linter in l:linters
|
||||
call s:ExecuteRename(l:linter, {
|
||||
\ 'old_name': l:old_name,
|
||||
\ 'new_name': l:new_name,
|
||||
\})
|
||||
|
@ -9,11 +9,11 @@ let g:ale_max_signs = get(g:, 'ale_max_signs', -1)
|
||||
" 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_error = get(g:, 'ale_sign_error', 'E')
|
||||
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_warning = get(g:, 'ale_sign_warning', 'W')
|
||||
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)
|
||||
let g:ale_sign_info = get(g:, 'ale_sign_info', 'I')
|
||||
let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
|
||||
" 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.
|
||||
|
@ -102,8 +102,8 @@ function! ale#symbol#Search(args) abort
|
||||
call setbufvar(l:buffer, 'ale_symbol_request_made', 0)
|
||||
let l:Callback = function('s:OnReady', [l:query, l:options])
|
||||
|
||||
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||
if !empty(l:linter.lsp) && l:linter.lsp isnot# 'tsserver'
|
||||
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
|
||||
if l:linter.lsp isnot# 'tsserver'
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
endfor
|
||||
|
@ -21,11 +21,11 @@ function! s:OpenJDTLink(root, uri, line, column, options, result) abort
|
||||
call ale#util#Open(a:uri, a:line, a:column, a:options)
|
||||
autocmd AleURISchemes BufNewFile,BufReadPre jdt://** call ale#uri#jdt#ReadJDTLink(expand('<amatch>'))
|
||||
|
||||
if !empty(getbufvar(bufnr(''), 'ale_lsp_root', ''))
|
||||
if !empty(getbufvar(bufnr(''), 'ale_root', ''))
|
||||
return
|
||||
endif
|
||||
|
||||
let b:ale_lsp_root = a:root
|
||||
let b:ale_root = a:root
|
||||
set filetype=java
|
||||
|
||||
call setline(1, split(l:contents, '\n'))
|
||||
@ -39,6 +39,8 @@ endfunction
|
||||
function! ale#uri#jdt#OpenJDTLink(encoded_uri, line, column, options, conn_id) abort
|
||||
let l:found_eclipselsp = v:false
|
||||
|
||||
" We should only arrive here from a 'go to definition' request, so we'll
|
||||
" assume the eclipselsp linter is enabled.
|
||||
for l:linter in ale#linter#Get('java')
|
||||
if l:linter.name is# 'eclipselsp'
|
||||
let l:found_eclipselsp = v:true
|
||||
@ -81,14 +83,14 @@ endfunction
|
||||
|
||||
" Read jdt:// contents, as part of current project, into current buffer.
|
||||
function! ale#uri#jdt#ReadJDTLink(encoded_uri) abort
|
||||
if !empty(getbufvar(bufnr(''), 'ale_lsp_root', ''))
|
||||
if !empty(getbufvar(bufnr(''), 'ale_root', ''))
|
||||
return
|
||||
endif
|
||||
|
||||
let l:linter_map = ale#lsp_linter#GetLSPLinterMap()
|
||||
|
||||
for l:conn_id in keys(l:linter_map)
|
||||
if l:linter_map[l:conn_id] is# 'eclipselsp'
|
||||
for [l:conn_id, l:linter] in items(l:linter_map)
|
||||
if l:linter.name is# 'eclipselsp'
|
||||
let l:root = l:conn_id[stridx(l:conn_id, ':')+1:]
|
||||
endif
|
||||
endfor
|
||||
@ -98,7 +100,7 @@ function! ale#uri#jdt#ReadJDTLink(encoded_uri) abort
|
||||
endif
|
||||
|
||||
let l:uri = a:encoded_uri
|
||||
let b:ale_lsp_root = l:root
|
||||
let b:ale_root = l:root
|
||||
set filetype=java
|
||||
|
||||
call ale#lsp_linter#SendRequest(
|
||||
|
@ -522,7 +522,18 @@ function! ale#util#SetBufferContents(buffer, lines) abort
|
||||
|
||||
" Use a Vim API for setting lines in other buffers, if available.
|
||||
if l:has_bufline_api
|
||||
call setbufline(a:buffer, 1, l:new_lines)
|
||||
if has('nvim')
|
||||
" save and restore signs to avoid flickering
|
||||
let signs = sign_getplaced(a:buffer, {'group': 'ale'})[0].signs
|
||||
|
||||
call nvim_buf_set_lines(a:buffer, 0, l:first_line_to_remove, 0, l:new_lines)
|
||||
|
||||
" restore signs (invalid line numbers will be skipped)
|
||||
call sign_placelist(map(signs, {_, v -> extend(v, {'buffer': a:buffer})}))
|
||||
else
|
||||
call setbufline(a:buffer, 1, l:new_lines)
|
||||
endif
|
||||
|
||||
call deletebufline(a:buffer, l:first_line_to_remove, '$')
|
||||
" Fall back on setting lines the old way, for the current buffer.
|
||||
else
|
||||
|
@ -31,7 +31,8 @@ let g:ale_virtualtext_delay = get(g:, 'ale_virtualtext_delay', 10)
|
||||
" Controls the positioning of virtualtext
|
||||
let g:ale_virtualtext_column = get(g:, 'ale_virtualtext_column', 0)
|
||||
let g:ale_virtualtext_maxcolumn = get(g:, 'ale_virtualtext_maxcolumn', 0)
|
||||
let g:ale_virtualtext_single = get(g:,'ale_virtualtext_single',0)
|
||||
" If 1, only show the first problem with virtualtext.
|
||||
let g:ale_virtualtext_single = get(g:, 'ale_virtualtext_single', 1)
|
||||
|
||||
let s:cursor_timer = get(s:, 'cursor_timer', -1)
|
||||
let s:last_pos = get(s:, 'last_pos', [0, 0, 0])
|
||||
@ -273,6 +274,32 @@ function! ale#virtualtext#ShowCursorWarningWithDelay() abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#virtualtext#CompareSeverityPerLine(left, right) abort
|
||||
" Compare lines
|
||||
if a:left.lnum < a:right.lnum
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left.lnum > a:right.lnum
|
||||
return 1
|
||||
endif
|
||||
|
||||
let l:left_priority = ale#util#GetItemPriority(a:left)
|
||||
let l:right_priority = ale#util#GetItemPriority(a:right)
|
||||
|
||||
" Put highest priority items first.
|
||||
if l:left_priority > l:right_priority
|
||||
return -1
|
||||
endif
|
||||
|
||||
if l:left_priority < l:right_priority
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Put the first seen problem first.
|
||||
return a:left.col - a:right.col
|
||||
endfunction
|
||||
|
||||
function! ale#virtualtext#SetTexts(buffer, loclist) abort
|
||||
if !has('nvim') && s:emulate_virt
|
||||
return
|
||||
@ -280,17 +307,19 @@ function! ale#virtualtext#SetTexts(buffer, loclist) abort
|
||||
|
||||
call ale#virtualtext#Clear(a:buffer)
|
||||
|
||||
let l:filter = ale#Var(a:buffer,'virtualtext_single')
|
||||
let l:seen = {}
|
||||
let l:buffer_list = filter(copy(a:loclist), 'v:val.bufnr == a:buffer')
|
||||
|
||||
for l:item in a:loclist
|
||||
if l:item.bufnr == a:buffer
|
||||
let l:line = max([1, l:item.lnum])
|
||||
if ale#Var(a:buffer,'virtualtext_single')
|
||||
" If we want a single problem per line, sort items on each line by
|
||||
" highest severity and then lowest column position, then de-duplicate
|
||||
" the items by line.
|
||||
call uniq(
|
||||
\ sort(l:buffer_list, function('ale#virtualtext#CompareSeverityPerLine')),
|
||||
\ {a, b -> a.lnum - b.lnum}
|
||||
\)
|
||||
endif
|
||||
|
||||
if !has_key(l:seen,l:line) || l:filter == 0
|
||||
call ale#virtualtext#ShowMessage(a:buffer, l:item)
|
||||
let l:seen[l:line] = 1
|
||||
endif
|
||||
endif
|
||||
for l:item in l:buffer_list
|
||||
call ale#virtualtext#ShowMessage(a:buffer, l:item)
|
||||
endfor
|
||||
endfunction
|
||||
|
Reference in New Issue
Block a user