mirror of
https://github.com/amix/vimrc
synced 2025-06-16 09:35:01 +08:00
update plugins
ran the plugin update script
This commit is contained in:
@ -96,6 +96,13 @@ function! ale#assert#Fixer(expected_result) abort
|
||||
AssertEqual a:expected_result, l:result
|
||||
endfunction
|
||||
|
||||
function! ale#assert#FixerNotExecuted() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1]
|
||||
|
||||
Assert empty(l:result), "The fixer will be executed when it shouldn't be"
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LinterNotExecuted() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
@ -158,6 +165,7 @@ endfunction
|
||||
function! ale#assert#SetUpFixerTestCommands() abort
|
||||
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
||||
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
|
||||
command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
|
||||
endfunction
|
||||
|
||||
" A dummy function for making sure this module is loaded.
|
||||
@ -316,4 +324,8 @@ function! ale#assert#TearDownFixerTest() abort
|
||||
if exists(':AssertFixer')
|
||||
delcommand AssertFixer
|
||||
endif
|
||||
|
||||
if exists(':AssertFixerNotExecuted')
|
||||
delcommand AssertFixerNotExecuted
|
||||
endif
|
||||
endfunction
|
||||
|
@ -23,27 +23,9 @@ function! ale#c#GetBuildDirectory(buffer) abort
|
||||
return l:build_dir
|
||||
endif
|
||||
|
||||
return ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
|
||||
endfunction
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
|
||||
function! ale#c#FindProjectRoot(buffer) abort
|
||||
for l:project_filename in g:__ale_c_project_filenames
|
||||
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
|
||||
|
||||
if !empty(l:full_path)
|
||||
let l:path = fnamemodify(l:full_path, ':h')
|
||||
|
||||
" Correct .git path detection.
|
||||
if fnamemodify(l:path, ':t') is# '.git'
|
||||
let l:path = fnamemodify(l:path, ':h')
|
||||
endif
|
||||
|
||||
return l:path
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
return ale#path#Dirname(l:json_file)
|
||||
endfunction
|
||||
|
||||
function! ale#c#AreSpecialCharsBalanced(option) abort
|
||||
@ -120,7 +102,7 @@ endfunction
|
||||
|
||||
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||
if !g:ale_c_parse_makefile
|
||||
return ''
|
||||
return v:null
|
||||
endif
|
||||
|
||||
let l:buffer_filename = expand('#' . a:buffer . ':t')
|
||||
@ -140,14 +122,17 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||
return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, find the build subdirectory with compile commands
|
||||
" The subdirectory is returned without the trailing /
|
||||
" Given a buffer number, find the project directory containing
|
||||
" compile_commands.json, and the path to the compile_commands.json file.
|
||||
"
|
||||
" If compile_commands.json cannot be found, two empty strings will be
|
||||
" returned.
|
||||
function! ale#c#FindCompileCommands(buffer) abort
|
||||
" Look above the current source file to find compile_commands.json
|
||||
let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
if !empty(l:json_file)
|
||||
return l:json_file
|
||||
return [fnamemodify(l:json_file, ':h'), l:json_file]
|
||||
endif
|
||||
|
||||
" Search in build directories if we can't find it in the project.
|
||||
@ -157,12 +142,42 @@ function! ale#c#FindCompileCommands(buffer) abort
|
||||
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
|
||||
|
||||
if filereadable(l:json_file)
|
||||
return l:json_file
|
||||
return [l:path, l:json_file]
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return ''
|
||||
return ['', '']
|
||||
endfunction
|
||||
|
||||
" Find the project root for C/C++ projects.
|
||||
"
|
||||
" The location of compile_commands.json will be used to find project roots.
|
||||
"
|
||||
" If compile_commands.json cannot be found, other common configuration files
|
||||
" will be used to detect the project root.
|
||||
function! ale#c#FindProjectRoot(buffer) abort
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
" Fall back on detecting the project root based on other filenames.
|
||||
if empty(l:root)
|
||||
for l:project_filename in g:__ale_c_project_filenames
|
||||
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
|
||||
|
||||
if !empty(l:full_path)
|
||||
let l:path = fnamemodify(l:full_path, ':h')
|
||||
|
||||
" Correct .git path detection.
|
||||
if fnamemodify(l:path, ':t') is# '.git'
|
||||
let l:path = fnamemodify(l:path, ':h')
|
||||
endif
|
||||
|
||||
return l:path
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:root
|
||||
endfunction
|
||||
|
||||
" Cache compile_commands.json data in a Dictionary, so we don't need to read
|
||||
@ -194,10 +209,14 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
||||
let l:raw_data = []
|
||||
silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
|
||||
|
||||
if type(l:raw_data) isnot v:t_list
|
||||
let l:raw_data = []
|
||||
endif
|
||||
|
||||
let l:file_lookup = {}
|
||||
let l:dir_lookup = {}
|
||||
|
||||
for l:entry in l:raw_data
|
||||
for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : [])
|
||||
let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
|
||||
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
|
||||
|
||||
@ -274,25 +293,25 @@ function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetCFlags(buffer, output) abort
|
||||
let l:cflags = ' '
|
||||
let l:cflags = v:null
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
|
||||
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_compile_commands')
|
||||
let l:json_file = ale#c#FindCompileCommands(a:buffer)
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
if !empty(l:json_file)
|
||||
let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
|
||||
endif
|
||||
endif
|
||||
|
||||
if l:cflags is# ' '
|
||||
if l:cflags is v:null
|
||||
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
|
||||
endif
|
||||
|
||||
return l:cflags
|
||||
return l:cflags isnot v:null ? l:cflags : ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetMakeCommand(buffer) abort
|
||||
|
@ -169,7 +169,7 @@ function! s:ReplaceCompletionOptions() abort
|
||||
let b:ale_old_omnifunc = &l:omnifunc
|
||||
endif
|
||||
|
||||
let &l:omnifunc = 'ale#completion#OmniFunc'
|
||||
let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
|
||||
endif
|
||||
|
||||
if l:source is# 'ale-automatic'
|
||||
@ -216,18 +216,6 @@ function! ale#completion#GetCompletionPosition() abort
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionResult() abort
|
||||
" Parse a new response if there is one.
|
||||
if exists('b:ale_completion_response')
|
||||
\&& exists('b:ale_completion_parser')
|
||||
let l:response = b:ale_completion_response
|
||||
let l:parser = b:ale_completion_parser
|
||||
|
||||
unlet b:ale_completion_response
|
||||
unlet b:ale_completion_parser
|
||||
|
||||
let b:ale_completion_result = function(l:parser)(l:response)
|
||||
endif
|
||||
|
||||
if exists('b:ale_completion_result')
|
||||
return b:ale_completion_result
|
||||
endif
|
||||
@ -235,7 +223,7 @@ function! ale#completion#GetCompletionResult() abort
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
function! ale#completion#OmniFunc(findstart, base) abort
|
||||
function! ale#completion#AutomaticOmniFunc(findstart, base) abort
|
||||
if a:findstart
|
||||
return ale#completion#GetCompletionPosition()
|
||||
else
|
||||
@ -247,15 +235,20 @@ function! ale#completion#OmniFunc(findstart, base) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Show(response, completion_parser) abort
|
||||
function! ale#completion#Show(result) abort
|
||||
if ale#util#Mode() isnot# 'i'
|
||||
return
|
||||
endif
|
||||
|
||||
" Set the list in the buffer, temporarily replace omnifunc with our
|
||||
" function, and then start omni-completion.
|
||||
let b:ale_completion_response = a:response
|
||||
let b:ale_completion_parser = a:completion_parser
|
||||
let b:ale_completion_result = a:result
|
||||
|
||||
" Don't try to open the completion menu if there's nothing to show.
|
||||
if empty(b:ale_completion_result)
|
||||
return
|
||||
endif
|
||||
|
||||
" Replace completion options shortly before opening the menu.
|
||||
call s:ReplaceCompletionOptions()
|
||||
|
||||
@ -279,6 +272,7 @@ function! s:CompletionStillValid(request_id) abort
|
||||
\&& (
|
||||
\ b:ale_completion_info.column == l:column
|
||||
\ || b:ale_completion_info.source is# 'deoplete'
|
||||
\ || b:ale_completion_info.source is# 'ale-omnifunc'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
@ -474,8 +468,7 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
||||
endif
|
||||
elseif l:command is# 'completionEntryDetails'
|
||||
call ale#completion#Show(
|
||||
\ a:response,
|
||||
\ 'ale#completion#ParseTSServerCompletionEntryDetails',
|
||||
\ ale#completion#ParseTSServerCompletionEntryDetails(a:response),
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
@ -487,8 +480,7 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort
|
||||
endif
|
||||
|
||||
call ale#completion#Show(
|
||||
\ a:response,
|
||||
\ 'ale#completion#ParseLSPCompletions',
|
||||
\ ale#completion#ParseLSPCompletions(a:response),
|
||||
\)
|
||||
endfunction
|
||||
|
||||
@ -529,10 +521,7 @@ function! s:OnReady(linter, lsp_details) abort
|
||||
let l:message = ale#lsp#message#Completion(
|
||||
\ l:buffer,
|
||||
\ b:ale_completion_info.line,
|
||||
\ min([
|
||||
\ b:ale_completion_info.line_length,
|
||||
\ b:ale_completion_info.column,
|
||||
\ ]) + 1,
|
||||
\ b:ale_completion_info.column,
|
||||
\ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix),
|
||||
\)
|
||||
endif
|
||||
@ -570,7 +559,7 @@ function! ale#completion#GetCompletions(source) abort
|
||||
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
|
||||
|
||||
if a:source is# 'ale-automatic' && empty(l:prefix)
|
||||
return
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:line_length = len(getline('.'))
|
||||
@ -589,11 +578,40 @@ function! ale#completion#GetCompletions(source) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:Callback = function('s:OnReady')
|
||||
|
||||
let l:started = 0
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
let l:started = 1
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:started
|
||||
endfunction
|
||||
|
||||
function! ale#completion#OmniFunc(findstart, base) abort
|
||||
if a:findstart
|
||||
let l:started = ale#completion#GetCompletions('ale-omnifunc')
|
||||
|
||||
if !l:started
|
||||
" This is the special value for cancelling completions silently.
|
||||
" See :help complete-functions
|
||||
return -3
|
||||
endif
|
||||
|
||||
return ale#completion#GetCompletionPosition()
|
||||
else
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
|
||||
while l:result is v:null && !complete_check()
|
||||
sleep 2ms
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
endwhile
|
||||
|
||||
return l:result isnot v:null ? l:result : []
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:TimerHandler(...) abort
|
||||
|
@ -238,6 +238,12 @@ function! ale#debugging#Info() abort
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToClipboard() abort
|
||||
if !has('clipboard')
|
||||
call s:Echo('clipboard not available. Try :ALEInfoToFile instead.')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
redir => l:output
|
||||
silent call ale#debugging#Info()
|
||||
redir END
|
||||
|
@ -2,47 +2,60 @@ call ale#Set('fix_on_save_ignore', {})
|
||||
|
||||
" Apply fixes queued up for buffers which may be hidden.
|
||||
" Vim doesn't let you modify hidden buffers.
|
||||
function! ale#fix#ApplyQueuedFixes() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:data = get(g:ale_fix_buffer_data, l:buffer, {'done': 0})
|
||||
function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||
let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0})
|
||||
let l:has_bufline_api = exists('*deletebufline') && exists('*setbufline')
|
||||
|
||||
if !l:data.done
|
||||
if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr(''))
|
||||
return
|
||||
endif
|
||||
|
||||
call remove(g:ale_fix_buffer_data, l:buffer)
|
||||
call remove(g:ale_fix_buffer_data, a:buffer)
|
||||
|
||||
if l:data.changes_made
|
||||
let l:start_line = len(l:data.output) + 1
|
||||
let l:end_line = len(l:data.lines_before)
|
||||
|
||||
if l:end_line >= l:start_line
|
||||
let l:save = winsaveview()
|
||||
silent execute l:start_line . ',' . l:end_line . 'd_'
|
||||
call winrestview(l:save)
|
||||
endif
|
||||
|
||||
" If the file is in DOS mode, we have to remove carriage returns from
|
||||
" the ends of lines before calling setline(), or we will see them
|
||||
" twice.
|
||||
let l:lines_to_set = getbufvar(l:buffer, '&fileformat') is# 'dos'
|
||||
let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos'
|
||||
\ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')')
|
||||
\ : l:data.output
|
||||
let l:first_line_to_remove = len(l:new_lines) + 1
|
||||
|
||||
call setline(1, l:lines_to_set)
|
||||
" 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)
|
||||
call deletebufline(a:buffer, l:first_line_to_remove, '$')
|
||||
" Fall back on setting lines the old way, for the current buffer.
|
||||
else
|
||||
let l:old_line_length = len(l:data.lines_before)
|
||||
|
||||
if l:old_line_length >= l:first_line_to_remove
|
||||
let l:save = winsaveview()
|
||||
silent execute
|
||||
\ l:first_line_to_remove . ',' . l:old_line_length . 'd_'
|
||||
call winrestview(l:save)
|
||||
endif
|
||||
|
||||
call setline(1, l:new_lines)
|
||||
endif
|
||||
|
||||
if l:data.should_save
|
||||
if empty(&buftype)
|
||||
noautocmd :w!
|
||||
if a:buffer is bufnr('')
|
||||
if empty(&buftype)
|
||||
noautocmd :w!
|
||||
else
|
||||
set nomodified
|
||||
endif
|
||||
else
|
||||
set nomodified
|
||||
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
|
||||
call setbufvar(a:buffer, '&modified', 0)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if l:data.should_save
|
||||
let l:should_lint = g:ale_fix_on_save
|
||||
\ && ale#Var(l:buffer, 'lint_on_save')
|
||||
\ && ale#Var(a:buffer, 'lint_on_save')
|
||||
else
|
||||
let l:should_lint = l:data.changes_made
|
||||
endif
|
||||
@ -53,7 +66,7 @@ function! ale#fix#ApplyQueuedFixes() abort
|
||||
" fixing problems.
|
||||
if g:ale_enabled
|
||||
\&& l:should_lint
|
||||
\&& !ale#events#QuitRecently(l:buffer)
|
||||
\&& !ale#events#QuitRecently(a:buffer)
|
||||
call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
|
||||
endif
|
||||
endfunction
|
||||
@ -84,7 +97,7 @@ function! ale#fix#ApplyFixes(buffer, output) abort
|
||||
|
||||
" We can only change the lines of a buffer which is currently open,
|
||||
" so try and apply the fixes to the current buffer.
|
||||
call ale#fix#ApplyQueuedFixes()
|
||||
call ale#fix#ApplyQueuedFixes(a:buffer)
|
||||
endfunction
|
||||
|
||||
function! s:HandleExit(job_info, buffer, job_output, data) abort
|
||||
@ -400,5 +413,4 @@ endfunction
|
||||
" Set up an autocmd command to try and apply buffer fixes when available.
|
||||
augroup ALEBufferFixGroup
|
||||
autocmd!
|
||||
autocmd BufEnter * call ale#fix#ApplyQueuedFixes()
|
||||
augroup END
|
||||
autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand('<abuf>')))
|
||||
|
@ -305,6 +305,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['tex'],
|
||||
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
|
||||
\ },
|
||||
\ 'pgformatter': {
|
||||
\ 'function': 'ale#fixers#pgformatter#Fix',
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'A PostgreSQL SQL syntax beautifier',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
|
@ -35,9 +35,18 @@ endfunction
|
||||
|
||||
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
|
||||
|
||||
if empty(l:config)
|
||||
" Use the configuration file from the options, if configured.
|
||||
if l:options =~# '\v(^| )-c|(^| )--config'
|
||||
let l:config = ''
|
||||
let l:has_config = 1
|
||||
else
|
||||
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
||||
let l:has_config = !empty(l:config)
|
||||
endif
|
||||
|
||||
if !l:has_config
|
||||
return 0
|
||||
endif
|
||||
|
||||
@ -45,6 +54,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
|
||||
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
|
||||
\}
|
||||
@ -54,6 +64,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
if ale#semver#GTE(a:version, [4, 9, 0])
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
|
||||
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
|
||||
\}
|
||||
@ -61,7 +72,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' -c ' . ale#Escape(l:config)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
|
||||
\ . ' --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
|
12
sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim
Normal file
12
sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim
Normal file
@ -0,0 +1,12 @@
|
||||
call ale#Set('sql_pgformatter_executable', 'pg_format')
|
||||
call ale#Set('sql_pgformatter_options', '')
|
||||
|
||||
function! ale#fixers#pgformatter#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'sql_pgformatter_executable')
|
||||
let l:options = ale#Var(a:buffer, 'sql_pgformatter_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||
\}
|
||||
endfunction
|
@ -3,15 +3,17 @@ scriptencoding utf-8
|
||||
" Description: Utilities for ccls
|
||||
|
||||
function! ale#handlers#ccls#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls-root')
|
||||
" Try to find ccls configuration files first.
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root')
|
||||
|
||||
if empty(l:project_root)
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
if empty(l:config)
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls')
|
||||
endif
|
||||
|
||||
if empty(l:project_root)
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls')
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
endif
|
||||
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
" Fall back on default project root detection.
|
||||
return ale#c#FindProjectRoot(a:buffer)
|
||||
endfunction
|
||||
|
@ -11,6 +11,7 @@ let s:pragma_error = '#pragma once in main file'
|
||||
" <stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)
|
||||
" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
|
||||
let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
|
||||
let s:inline_pattern = '\v inlined from .* at \<stdin\>:(\d+):(\d+):$'
|
||||
|
||||
function! s:IsHeaderFile(filename) abort
|
||||
return a:filename =~? '\v\.(h|hpp)$'
|
||||
@ -25,6 +26,28 @@ function! s:RemoveUnicodeQuotes(text) abort
|
||||
return l:text
|
||||
endfunction
|
||||
|
||||
function! s:ParseInlinedFunctionProblems(buffer, lines) abort
|
||||
let l:output = []
|
||||
let l:pos_match = []
|
||||
|
||||
for l:line in a:lines
|
||||
let l:match = matchlist(l:line, s:pattern)
|
||||
|
||||
if !empty(l:match) && !empty(l:pos_match)
|
||||
call add(l:output, {
|
||||
\ 'lnum': str2nr(l:pos_match[1]),
|
||||
\ 'col': str2nr(l:pos_match[2]),
|
||||
\ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W',
|
||||
\ 'text': s:RemoveUnicodeQuotes(l:match[5]),
|
||||
\})
|
||||
endif
|
||||
|
||||
let l:pos_match = matchlist(l:line, s:inline_pattern)
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
" Report problems inside of header files just for gcc and clang
|
||||
function! s:ParseProblemsInHeaders(buffer, lines) abort
|
||||
let l:output = []
|
||||
@ -129,6 +152,7 @@ endfunction
|
||||
function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort
|
||||
let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
|
||||
|
||||
call extend(l:output, s:ParseInlinedFunctionProblems(a:buffer, a:lines))
|
||||
call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines))
|
||||
|
||||
return l:output
|
||||
|
@ -26,41 +26,6 @@ endif
|
||||
let s:MAX_POS_VALUES = 8
|
||||
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
|
||||
|
||||
" Check if we have neovim's buffer highlight API
|
||||
"
|
||||
" Below we define some functions' implementation conditionally if this API
|
||||
" exists or not.
|
||||
"
|
||||
" The API itself is more ergonomic and neovim performs highlights positions
|
||||
" rebases during edits so we see less stalled highlights.
|
||||
let s:nvim_api = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
|
||||
|
||||
function! ale#highlight#HasNeovimApi() abort
|
||||
return s:nvim_api
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#nvim_buf_clear_namespace(...) abort
|
||||
return call('nvim_buf_clear_namespace', a:000)
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#nvim_buf_add_highlight(...) abort
|
||||
return call('nvim_buf_add_highlight', a:000)
|
||||
endfunction
|
||||
|
||||
function! s:ale_nvim_highlight_id(bufnr) abort
|
||||
let l:id = getbufvar(a:bufnr, 'ale_nvim_highlight_id', -1)
|
||||
|
||||
if l:id is -1
|
||||
" NOTE: This will highlight nothing but will allocate new id
|
||||
let l:id = ale#highlight#nvim_buf_add_highlight(
|
||||
\ a:bufnr, 0, '', 0, 0, -1
|
||||
\)
|
||||
call setbufvar(a:bufnr, 'ale_nvim_highlight_id', l:id)
|
||||
endif
|
||||
|
||||
return l:id
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
|
||||
if a:line >= a:end_line
|
||||
" For single lines, just return the one position.
|
||||
@ -86,88 +51,11 @@ endfunction
|
||||
" except these which have matching loclist item entries.
|
||||
|
||||
function! ale#highlight#RemoveHighlights() abort
|
||||
if ale#highlight#HasNeovimApi()
|
||||
if get(b:, 'ale_nvim_highlight_id', 0)
|
||||
let l:bufnr = bufnr('%')
|
||||
" NOTE: 0, -1 means from 0 line till the end of buffer
|
||||
call ale#highlight#nvim_buf_clear_namespace(
|
||||
\ l:bufnr,
|
||||
\ b:ale_nvim_highlight_id,
|
||||
\ 0, -1
|
||||
\)
|
||||
for l:match in getmatches()
|
||||
if l:match.group =~# '^ALE'
|
||||
call matchdelete(l:match.id)
|
||||
endif
|
||||
else
|
||||
for l:match in getmatches()
|
||||
if l:match.group =~# '^ALE'
|
||||
call matchdelete(l:match.id)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:highlight_line(bufnr, lnum, group) abort
|
||||
if ale#highlight#HasNeovimApi()
|
||||
let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr)
|
||||
call ale#highlight#nvim_buf_add_highlight(
|
||||
\ a:bufnr, l:highlight_id, a:group,
|
||||
\ a:lnum - 1, 0, -1
|
||||
\)
|
||||
else
|
||||
call matchaddpos(a:group, [a:lnum])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:highlight_range(bufnr, range, group) abort
|
||||
if ale#highlight#HasNeovimApi()
|
||||
let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr)
|
||||
" NOTE: lines and columns indicies are 0-based in nvim_buf_* API.
|
||||
let l:lnum = a:range.lnum - 1
|
||||
let l:end_lnum = a:range.end_lnum - 1
|
||||
let l:col = a:range.col - 1
|
||||
let l:end_col = a:range.end_col
|
||||
|
||||
if l:lnum >= l:end_lnum
|
||||
" For single lines, just return the one position.
|
||||
call ale#highlight#nvim_buf_add_highlight(
|
||||
\ a:bufnr, l:highlight_id, a:group,
|
||||
\ l:lnum, l:col, l:end_col
|
||||
\)
|
||||
else
|
||||
" highlight first line from start till the line end
|
||||
call ale#highlight#nvim_buf_add_highlight(
|
||||
\ a:bufnr, l:highlight_id, a:group,
|
||||
\ l:lnum, l:col, -1
|
||||
\)
|
||||
|
||||
" highlight all lines between the first and last entirely
|
||||
let l:cur = l:lnum + 1
|
||||
|
||||
while l:cur < l:end_lnum
|
||||
call ale#highlight#nvim_buf_add_highlight(
|
||||
\ a:bufnr, l:highlight_id, a:group,
|
||||
\ l:cur, 0, -1
|
||||
\ )
|
||||
let l:cur += 1
|
||||
endwhile
|
||||
|
||||
call ale#highlight#nvim_buf_add_highlight(
|
||||
\ a:bufnr, l:highlight_id, a:group,
|
||||
\ l:end_lnum, 0, l:end_col
|
||||
\)
|
||||
endif
|
||||
else
|
||||
" Set all of the positions, which are chunked into Lists which
|
||||
" are as large as will be accepted by matchaddpos.
|
||||
call map(
|
||||
\ ale#highlight#CreatePositions(
|
||||
\ a:range.lnum,
|
||||
\ a:range.col,
|
||||
\ a:range.end_lnum,
|
||||
\ a:range.end_col
|
||||
\ ),
|
||||
\ 'matchaddpos(a:group, v:val)'
|
||||
\)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:highlight_line(bufnr, lnum, group) abort
|
||||
|
@ -111,7 +111,7 @@ function! ale#loclist_jumping#Jump(direction, ...) abort
|
||||
|
||||
if !empty(l:nearest)
|
||||
normal! m`
|
||||
call cursor(l:nearest)
|
||||
call cursor([l:nearest[0], max([l:nearest[1], 1])])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -321,7 +321,69 @@ endfunction
|
||||
|
||||
function! s:SendInitMessage(conn) abort
|
||||
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
|
||||
\ ale#lsp#message#Initialize(a:conn.root, a:conn.init_options),
|
||||
\ ale#lsp#message#Initialize(
|
||||
\ a:conn.root,
|
||||
\ a:conn.init_options,
|
||||
\ {
|
||||
\ 'workspace': {
|
||||
\ 'applyEdit': v:false,
|
||||
\ 'didChangeConfiguration': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'symbol': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'workspaceFolders': v:false,
|
||||
\ 'configuration': v:false,
|
||||
\ },
|
||||
\ 'textDocument': {
|
||||
\ 'synchronization': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'willSave': v:false,
|
||||
\ 'willSaveWaitUntil': v:false,
|
||||
\ 'didSave': v:true,
|
||||
\ },
|
||||
\ 'completion': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'completionItem': {
|
||||
\ 'snippetSupport': v:false,
|
||||
\ 'commitCharactersSupport': v:false,
|
||||
\ 'documentationFormat': ['plaintext'],
|
||||
\ 'deprecatedSupport': v:false,
|
||||
\ 'preselectSupport': v:false,
|
||||
\ },
|
||||
\ 'contextSupport': v:false,
|
||||
\ },
|
||||
\ 'hover': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'contentFormat': ['plaintext'],
|
||||
\ },
|
||||
\ 'references': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'documentSymbol': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'hierarchicalDocumentSymbolSupport': v:false,
|
||||
\ },
|
||||
\ 'definition': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'linkSupport': v:false,
|
||||
\ },
|
||||
\ 'typeDefinition': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'publishDiagnostics': {
|
||||
\ 'relatedInformation': v:true,
|
||||
\ },
|
||||
\ 'codeAction': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'rename': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ },
|
||||
\ },
|
||||
\ ),
|
||||
\)
|
||||
let a:conn.init_request_id = l:init_id
|
||||
call s:SendMessageData(a:conn, l:init_data)
|
||||
|
@ -28,14 +28,13 @@ function! ale#lsp#message#GetNextVersionID() abort
|
||||
return l:id
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Initialize(root_path, initialization_options) abort
|
||||
" TODO: Define needed capabilities.
|
||||
function! ale#lsp#message#Initialize(root_path, options, capabilities) abort
|
||||
" NOTE: rootPath is deprecated in favour of rootUri
|
||||
return [0, 'initialize', {
|
||||
\ 'processId': getpid(),
|
||||
\ 'rootPath': a:root_path,
|
||||
\ 'capabilities': {},
|
||||
\ 'initializationOptions': a:initialization_options,
|
||||
\ 'capabilities': a:capabilities,
|
||||
\ 'initializationOptions': a:options,
|
||||
\ 'rootUri': ale#path#ToURI(a:root_path),
|
||||
\}]
|
||||
endfunction
|
||||
|
@ -31,7 +31,7 @@ endfunction
|
||||
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
||||
let l:linter_name = s:lsp_linter_map[a:conn_id]
|
||||
let l:filename = ale#path#FromURI(a:response.params.uri)
|
||||
let l:buffer = bufnr(l:filename)
|
||||
let l:buffer = bufnr('^' . l:filename . '$')
|
||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
@ -49,7 +49,7 @@ endfunction
|
||||
|
||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
let l:linter_name = 'tsserver'
|
||||
let l:buffer = bufnr(a:response.body.file)
|
||||
let l:buffer = bufnr('^' . a:response.body.file . '$')
|
||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
|
@ -25,7 +25,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
|
||||
\|| filereadable(l:path . '/tox.ini')
|
||||
\|| filereadable(l:path . '/mypy.ini')
|
||||
\|| filereadable(l:path . '/pycodestyle.cfg')
|
||||
\|| filereadable(l:path . '/flake8.cfg')
|
||||
\|| filereadable(l:path . '/.flake8')
|
||||
\|| filereadable(l:path . '/.flake8rc')
|
||||
\|| filereadable(l:path . '/pylama.ini')
|
||||
\|| filereadable(l:path . '/pylintrc')
|
||||
|
Reference in New Issue
Block a user