summaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
Diffstat (limited to 'autoload')
-rw-r--r--autoload/ale/c.vim1
-rw-r--r--autoload/ale/codefix.vim5
-rw-r--r--autoload/ale/cursor.vim22
-rw-r--r--autoload/ale/fix/registry.vim4
-rw-r--r--autoload/ale/fixers/isort.vim27
-rw-r--r--autoload/ale/floating_preview.vim91
-rw-r--r--autoload/ale/handlers/inko.vim37
-rw-r--r--autoload/ale/hover.vim9
-rw-r--r--autoload/ale/linter.vim1
-rw-r--r--autoload/ale/lsp_linter.vim13
-rw-r--r--autoload/ale/python.vim2
-rw-r--r--autoload/ale/util.vim9
12 files changed, 196 insertions, 25 deletions
diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim
index cff53125..c7b1e20a 100644
--- a/autoload/ale/c.vim
+++ b/autoload/ale/c.vim
@@ -152,6 +152,7 @@ function! ale#c#ParseCFlags(path_prefix, should_quote, raw_arguments) abort
\ || stridx(l:option, '-idirafter') == 0
\ || stridx(l:option, '-iframework') == 0
\ || stridx(l:option, '-include') == 0
+ \ || stridx(l:option, '-imacros') == 0
if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
let l:arg = join(split(l:option, '\zs')[2:], '')
let l:option = '-I'
diff --git a/autoload/ale/codefix.vim b/autoload/ale/codefix.vim
index 69bf36fa..4a78063b 100644
--- a/autoload/ale/codefix.vim
+++ b/autoload/ale/codefix.vim
@@ -261,7 +261,10 @@ function! ale#codefix#HandleLSPResponse(conn_id, response) abort
" Send the results to the menu callback, if set.
if l:MenuCallback isnot v:null
- call l:MenuCallback(map(copy(l:result), '[''lsp'', v:val]'))
+ call l:MenuCallback(
+ \ l:data,
+ \ map(copy(l:result), '[''lsp'', v:val]')
+ \)
return
endif
diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim
index 9ca6fb15..e8478e93 100644
--- a/autoload/ale/cursor.vim
+++ b/autoload/ale/cursor.vim
@@ -9,7 +9,6 @@ let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10)
let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s')
let s:cursor_timer = -1
-let s:last_pos = [0, 0, 0]
function! ale#cursor#TruncatedEcho(original_message) abort
let l:message = a:original_message
@@ -118,14 +117,18 @@ function! ale#cursor#EchoCursorWarningWithDelay() abort
let l:pos = getpos('.')[0:2]
+ if !exists('w:last_pos')
+ let w:last_pos = [0, 0, 0]
+ endif
+
" Check the current buffer, line, and column number against the last
" recorded position. If the position has actually changed, *then*
" we should echo something. Otherwise we can end up doing processing
" the echo message far too frequently.
- if l:pos != s:last_pos
+ if l:pos != w:last_pos
let l:delay = ale#Var(l:buffer, 'echo_delay')
- let s:last_pos = l:pos
+ let w:last_pos = l:pos
let s:cursor_timer = timer_start(
\ l:delay,
\ function('ale#cursor#EchoCursorWarning')
@@ -139,11 +142,16 @@ function! s:ShowCursorDetailForItem(loc, options) abort
let s:last_detailed_line = line('.')
let l:message = get(a:loc, 'detail', a:loc.text)
let l:lines = split(l:message, "\n")
- call ale#preview#Show(l:lines, {'stay_here': l:stay_here})
- " Clear the echo message if we manually displayed details.
- if !l:stay_here
- execute 'echo'
+ if g:ale_floating_preview || g:ale_detail_to_floating_preview
+ call ale#floating_preview#Show(l:lines)
+ else
+ call ale#preview#Show(l:lines, {'stay_here': l:stay_here})
+
+ " Clear the echo message if we manually displayed details.
+ if !l:stay_here
+ execute 'echo'
+ endif
endif
endfunction
diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim
index f5fadcca..f514466e 100644
--- a/autoload/ale/fix/registry.vim
+++ b/autoload/ale/fix/registry.vim
@@ -153,7 +153,7 @@ let s:default_registry = {
\ },
\ 'scalafmt': {
\ 'function': 'ale#fixers#scalafmt#Fix',
-\ 'suggested_filetypes': ['scala'],
+\ 'suggested_filetypes': ['sbt', 'scala'],
\ 'description': 'Fix Scala files using scalafmt',
\ },
\ 'sorbet': {
@@ -363,7 +363,7 @@ let s:default_registry = {
\ },
\ 'ktlint': {
\ 'function': 'ale#fixers#ktlint#Fix',
-\ 'suggested_filetypes': ['kt'],
+\ 'suggested_filetypes': ['kt', 'kotlin'],
\ 'description': 'Fix Kotlin files with ktlint.',
\ },
\ 'styler': {
diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim
index 9070fb27..55bb550e 100644
--- a/autoload/ale/fixers/isort.vim
+++ b/autoload/ale/fixers/isort.vim
@@ -2,24 +2,35 @@
" Description: Fixing Python imports with isort.
call ale#Set('python_isort_executable', 'isort')
-call ale#Set('python_isort_options', '')
call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0))
+call ale#Set('python_isort_options', '')
+call ale#Set('python_isort_auto_pipenv', 0)
+
+function! ale#fixers#isort#GetExecutable(buffer) abort
+ if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_isort_auto_pipenv'))
+ \ && ale#python#PipenvPresent(a:buffer)
+ return 'pipenv'
+ endif
+
+ return ale#python#FindExecutable(a:buffer, 'python_isort', ['isort'])
+endfunction
function! ale#fixers#isort#Fix(buffer) abort
let l:options = ale#Var(a:buffer, 'python_isort_options')
- let l:executable = ale#python#FindExecutable(
- \ a:buffer,
- \ 'python_isort',
- \ ['isort'],
- \)
+ let l:executable = ale#fixers#isort#GetExecutable(a:buffer)
+
+ let l:exec_args = l:executable =~? 'pipenv$'
+ \ ? ' run isort'
+ \ : ''
- if !executable(l:executable)
+ if !executable(l:executable) && l:executable isnot# 'pipenv'
return 0
endif
return {
\ 'command': ale#path#BufferCdString(a:buffer)
- \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -',
+ \ . ale#Escape(l:executable) . l:exec_args
+ \ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\}
endfunction
diff --git a/autoload/ale/floating_preview.vim b/autoload/ale/floating_preview.vim
new file mode 100644
index 00000000..e6a75689
--- /dev/null
+++ b/autoload/ale/floating_preview.vim
@@ -0,0 +1,91 @@
+" Author: Jan-Grimo Sobez <jan-grimo.sobez@phys.chem.ethz.ch>
+" Author: Kevin Clark <kevin.clark@gmail.com>
+" Description: Floating preview window for showing whatever information in.
+
+" Precondition: exists('*nvim_open_win')
+
+function! ale#floating_preview#Show(lines, ...) abort
+ if !exists('*nvim_open_win')
+ execute 'echom ''Floating windows not supported in this vim instance.'''
+
+ return
+ endif
+
+ " Remove the close autocmd so it doesn't happen mid update
+ augroup ale_floating_preview_window
+ autocmd!
+ augroup END
+
+ let l:options = get(a:000, 0, {})
+
+ " Only create a new window if we need it
+ if !exists('w:preview') || index(nvim_list_wins(), w:preview['id']) is# -1
+ call s:Create(l:options)
+ else
+ call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:true)
+ endif
+
+ " Execute commands in window context
+ let l:parent_window = nvim_get_current_win()
+
+ call nvim_set_current_win(w:preview['id'])
+
+ for l:command in get(l:options, 'commands', [])
+ call execute(l:command)
+ endfor
+
+ call nvim_set_current_win(l:parent_window)
+
+ " Return to parent context on move
+ augroup ale_floating_preview_window
+ autocmd!
+
+ if g:ale_close_preview_on_insert
+ autocmd CursorMoved,TabLeave,WinLeave,InsertEnter <buffer> ++once call s:Close()
+ else
+ autocmd CursorMoved,TabLeave,WinLeave <buffer> ++once call s:Close()
+ endif
+ augroup END
+
+ let l:width = max(map(copy(a:lines), 'strdisplaywidth(v:val)'))
+ let l:height = min([len(a:lines), 10])
+ call nvim_win_set_width(w:preview['id'], l:width)
+ call nvim_win_set_height(w:preview['id'], l:height)
+
+ call nvim_buf_set_lines(w:preview['buffer'], 0, -1, v:false, a:lines)
+ call nvim_buf_set_option(w:preview['buffer'], 'modified', v:false)
+ call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:false)
+endfunction
+
+function! s:Create(options) abort
+ let l:buffer = nvim_create_buf(v:false, v:false)
+ let l:winid = nvim_open_win(l:buffer, v:false, {
+ \ 'relative': 'cursor',
+ \ 'row': 1,
+ \ 'col': 0,
+ \ 'width': 42,
+ \ 'height': 4,
+ \ 'style': 'minimal'
+ \ })
+ call nvim_buf_set_option(l:buffer, 'buftype', 'acwrite')
+ call nvim_buf_set_option(l:buffer, 'bufhidden', 'delete')
+ call nvim_buf_set_option(l:buffer, 'swapfile', v:false)
+ call nvim_buf_set_option(l:buffer, 'filetype', get(a:options, 'filetype', 'ale-preview'))
+
+ let w:preview = {'id': l:winid, 'buffer': l:buffer}
+endfunction
+
+function! s:Close() abort
+ if !exists('w:preview')
+ return
+ endif
+
+ call setbufvar(w:preview['buffer'], '&modified', 0)
+
+ if win_id2win(w:preview['id']) > 0
+ execute win_id2win(w:preview['id']).'wincmd c'
+ endif
+
+ unlet w:preview
+endfunction
+
diff --git a/autoload/ale/handlers/inko.vim b/autoload/ale/handlers/inko.vim
new file mode 100644
index 00000000..73f06871
--- /dev/null
+++ b/autoload/ale/handlers/inko.vim
@@ -0,0 +1,37 @@
+" Author: Yorick Peterse <yorick@yorickpeterse.com>
+" Description: output handlers for the Inko JSON format
+
+function! ale#handlers#inko#GetType(severity) abort
+ if a:severity is? 'warning'
+ return 'W'
+ endif
+
+ return 'E'
+endfunction
+
+function! ale#handlers#inko#Handle(buffer, lines) abort
+ try
+ let l:errors = json_decode(join(a:lines, ''))
+ catch
+ return []
+ endtry
+
+ if empty(l:errors)
+ return []
+ endif
+
+ let l:output = []
+ let l:dir = expand('#' . a:buffer . ':p:h')
+
+ for l:error in l:errors
+ call add(l:output, {
+ \ 'filename': ale#path#GetAbsPath(l:dir, l:error['file']),
+ \ 'lnum': l:error['line'],
+ \ 'col': l:error['column'],
+ \ 'text': l:error['message'],
+ \ 'type': ale#handlers#inko#GetType(l:error['level']),
+ \})
+ endfor
+
+ return l:output
+endfunction
diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim
index 1d38f3b9..cb0379fd 100644
--- a/autoload/ale/hover.vim
+++ b/autoload/ale/hover.vim
@@ -46,6 +46,10 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort
call balloon_show(a:response.body.displayString)
elseif get(l:options, 'truncated_echo', 0)
call ale#cursor#TruncatedEcho(split(a:response.body.displayString, "\n")[0])
+ elseif g:ale_hover_to_floating_preview || g:ale_floating_preview
+ call ale#floating_preview#Show(split(a:response.body.displayString, "\n"), {
+ \ 'filetype': 'ale-preview.message',
+ \})
elseif g:ale_hover_to_preview
call ale#preview#Show(split(a:response.body.displayString, "\n"), {
\ 'filetype': 'ale-preview.message',
@@ -226,6 +230,11 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort
call balloon_show(join(l:lines, "\n"))
elseif get(l:options, 'truncated_echo', 0)
call ale#cursor#TruncatedEcho(l:lines[0])
+ elseif g:ale_hover_to_floating_preview || g:ale_floating_preview
+ call ale#floating_preview#Show(l:lines, {
+ \ 'filetype': 'ale-preview.message',
+ \ 'commands': l:commands,
+ \})
elseif g:ale_hover_to_preview
call ale#preview#Show(l:lines, {
\ 'filetype': 'ale-preview.message',
diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim
index 645c25f9..ba11e1eb 100644
--- a/autoload/ale/linter.vim
+++ b/autoload/ale/linter.vim
@@ -43,6 +43,7 @@ let s:default_ale_linters = {
\ 'go': ['gofmt', 'golint', 'go vet'],
\ 'hack': ['hack'],
\ 'help': [],
+\ 'inko': ['inko'],
\ 'perl': ['perlcritic'],
\ 'perl6': [],
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright'],
diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim
index dcd76e8f..628dde78 100644
--- a/autoload/ale/lsp_linter.vim
+++ b/autoload/ale/lsp_linter.vim
@@ -85,12 +85,18 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
endif
let l:info.syntax_loclist = l:thislist
- else
+ elseif a:error_type is# 'semantic'
if len(l:thislist) is 0 && len(get(l:info, 'semantic_loclist', [])) is 0
let l:no_changes = 1
endif
let l:info.semantic_loclist = l:thislist
+ else
+ if len(l:thislist) is 0 && len(get(l:info, 'suggestion_loclist', [])) is 0
+ let l:no_changes = 1
+ endif
+
+ let l:info.suggestion_loclist = l:thislist
endif
if l:no_changes
@@ -98,6 +104,7 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
endif
let l:loclist = get(l:info, 'semantic_loclist', [])
+ \ + get(l:info, 'suggestion_loclist', [])
\ + get(l:info, 'syntax_loclist', [])
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
@@ -150,6 +157,10 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
elseif get(a:response, 'type', '') is# 'event'
\&& get(a:response, 'event', '') is# 'syntaxDiag'
call s:HandleTSServerDiagnostics(a:response, 'syntax')
+ elseif get(a:response, 'type', '') is# 'event'
+ \&& get(a:response, 'event', '') is# 'suggestionDiag'
+ \&& get(g:, 'ale_lsp_suggestions', '1') == 1
+ call s:HandleTSServerDiagnostics(a:response, 'suggestion')
endif
endfunction
diff --git a/autoload/ale/python.vim b/autoload/ale/python.vim
index 7ed22367..fc6c1130 100644
--- a/autoload/ale/python.vim
+++ b/autoload/ale/python.vim
@@ -32,6 +32,8 @@ function! ale#python#FindProjectRootIni(buffer) abort
\|| filereadable(l:path . '/.pylintrc')
\|| filereadable(l:path . '/Pipfile')
\|| filereadable(l:path . '/Pipfile.lock')
+ \|| filereadable(l:path . '/poetry.lock')
+ \|| filereadable(l:path . '/pyproject.toml')
return l:path
endif
endfor
diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim
index fcc03eb7..1f396377 100644
--- a/autoload/ale/util.vim
+++ b/autoload/ale/util.vim
@@ -486,7 +486,7 @@ function! ale#util#Input(message, value) abort
endfunction
function! ale#util#HasBuflineApi() abort
- return exists('*deletebufline') && exists('*appendbufline') && exists('*getpos') && exists('*setpos')
+ return exists('*deletebufline') && exists('*setbufline')
endfunction
" Sets buffer contents to lines
@@ -507,11 +507,8 @@ function! ale#util#SetBufferContents(buffer, lines) abort
" Use a Vim API for setting lines in other buffers, if available.
if l:has_bufline_api
- let l:save_cursor = getpos('.')
- call deletebufline(a:buffer, 1, '$')
- call appendbufline(a:buffer, 1, l:new_lines)
- call deletebufline(a:buffer, 1, 1)
- call setpos('.', l:save_cursor)
+ 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 = line('$')