diff options
24 files changed, 238 insertions, 179 deletions
diff --git a/ale_linters/java/javac.vim b/ale_linters/java/javac.vim index e903210d..50cabacd 100644 --- a/ale_linters/java/javac.vim +++ b/ale_linters/java/javac.vim @@ -55,15 +55,14 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort if isdirectory(l:jaxb_dir) call add(l:sp_dirs, l:jaxb_dir) endif + endif - " Automatically include the test directory, but only for test code. - if expand('#' . a:buffer . ':p') =~? '\vsrc[/\\]test[/\\]java' - let l:test_dir = fnamemodify(l:src_dir, ':h:h:h') - \ . (has('win32') ? '\test\java\' : '/test/java/') + " Automatically include the test directory, but only for test code. + if expand('#' . a:buffer . ':p') =~? '\vsrc[/\\]test[/\\]java' + let l:test_dir = ale#path#FindNearestDirectory(a:buffer, 'src/test/java') - if isdirectory(l:test_dir) - call add(l:sp_dirs, l:test_dir) - endif + if isdirectory(l:test_dir) + call add(l:sp_dirs, l:test_dir) endif endif diff --git a/ale_linters/rust/rls.vim b/ale_linters/rust/rls.vim index cf34b43c..0e5c326c 100644 --- a/ale_linters/rust/rls.vim +++ b/ale_linters/rust/rls.vim @@ -3,6 +3,7 @@ call ale#Set('rust_rls_executable', 'rls') call ale#Set('rust_rls_toolchain', 'nightly') +call ale#Set('rust_rls_config', {}) function! ale_linters#rust#rls#GetCommand(buffer) abort let l:toolchain = ale#Var(a:buffer, 'rust_rls_toolchain') @@ -19,6 +20,7 @@ endfunction call ale#linter#Define('rust', { \ 'name': 'rls', \ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'rust_rls_config')}, \ 'executable': {b -> ale#Var(b, 'rust_rls_executable')}, \ 'command': function('ale_linters#rust#rls#GetCommand'), \ 'project_root': function('ale_linters#rust#rls#GetProjectRoot'), diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index 4a566d4f..48fa3963 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -165,14 +165,18 @@ function! s:ReplaceCompletionOptions() abort let &l:omnifunc = 'ale#completion#OmniFunc' - if !exists('b:ale_old_completopt') - let b:ale_old_completopt = &l:completeopt - endif + let l:info = get(b:, 'ale_completion_info', {}) - if &l:completeopt =~# 'preview' - let &l:completeopt = 'menu,menuone,preview,noselect,noinsert' - else - let &l:completeopt = 'menu,menuone,noselect,noinsert' + if !get(l:info, 'manual') + if !exists('b:ale_old_completeopt') + let b:ale_old_completeopt = &l:completeopt + endif + + if &l:completeopt =~# 'preview' + let &l:completeopt = 'menu,menuone,preview,noselect,noinsert' + else + let &l:completeopt = 'menu,menuone,noselect,noinsert' + endif endif endfunction @@ -186,9 +190,9 @@ function! ale#completion#RestoreCompletionOptions() abort unlet b:ale_old_omnifunc endif - if exists('b:ale_old_completopt') - let &l:completeopt = b:ale_old_completopt - unlet b:ale_old_completopt + if exists('b:ale_old_completeopt') + let &l:completeopt = b:ale_old_completeopt + unlet b:ale_old_completeopt endif endfunction @@ -236,7 +240,7 @@ function! ale#completion#Show(response, completion_parser) abort endfunction function! s:CompletionStillValid(request_id) abort - let [l:line, l:column] = getcurpos()[1:2] + let [l:line, l:column] = getpos('.')[1:2] return ale#util#Mode() is# 'i' \&& has_key(b:, 'ale_completion_info') @@ -503,22 +507,14 @@ function! s:OnReady(linter, lsp_details) abort endif endfunction -function! ale#completion#GetCompletions() abort - if !g:ale_completion_enabled - return - endif - - call ale#completion#AlwaysGetCompletions(1) -endfunction - " This function can be used to manually trigger autocomplete, even when " g:ale_completion_enabled is set to false -function! ale#completion#AlwaysGetCompletions(need_prefix) abort - let [l:line, l:column] = getcurpos()[1:2] +function! ale#completion#GetCompletions(manual) abort + let [l:line, l:column] = getpos('.')[1:2] let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column) - if a:need_prefix && empty(l:prefix) + if !a:manual && empty(l:prefix) return endif @@ -531,6 +527,7 @@ function! ale#completion#AlwaysGetCompletions(need_prefix) abort \ 'prefix': l:prefix, \ 'conn_id': 0, \ 'request_id': 0, + \ 'manual': a:manual, \} let l:buffer = bufnr('') @@ -544,14 +541,18 @@ function! ale#completion#AlwaysGetCompletions(need_prefix) abort endfunction function! s:TimerHandler(...) abort + if !g:ale_completion_enabled + return + endif + let s:timer_id = -1 - let [l:line, l:column] = getcurpos()[1:2] + let [l:line, l:column] = getpos('.')[1:2] " When running the timer callback, we have to be sure that the cursor " hasn't moved from where it was when we requested completions by typing. if s:timer_pos == [l:line, l:column] && ale#util#Mode() is# 'i' - call ale#completion#GetCompletions() + call ale#completion#GetCompletions(0) endif endfunction @@ -569,7 +570,7 @@ function! ale#completion#Queue() abort return endif - let s:timer_pos = getcurpos()[1:2] + let s:timer_pos = getpos('.')[1:2] if s:timer_pos == s:last_done_pos " Do not ask for completions if the cursor rests on the position we @@ -593,7 +594,7 @@ function! ale#completion#Done() abort call ale#completion#RestoreCompletionOptions() - let s:last_done_pos = getcurpos()[1:2] + let s:last_done_pos = getpos('.')[1:2] endfunction function! s:Setup(enabled) abort diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim index 6672c349..eea8ffe6 100644 --- a/autoload/ale/cursor.vim +++ b/autoload/ale/cursor.vim @@ -22,7 +22,7 @@ function! ale#cursor#TruncatedEcho(original_message) abort let l:shortmess_options = &l:shortmess try - let l:cursor_position = getcurpos() + let l:cursor_position = getpos('.') " The message is truncated and saved to the history. setlocal shortmess+=T @@ -44,7 +44,7 @@ function! ale#cursor#TruncatedEcho(original_message) abort " Reset the cursor position if we moved off the end of the line. " Using :norm and :echomsg can move the cursor off the end of the " line. - if l:cursor_position != getcurpos() + if l:cursor_position != getpos('.') call setpos('.', l:cursor_position) endif finally @@ -114,7 +114,7 @@ function! ale#cursor#EchoCursorWarningWithDelay() abort call s:StopCursorTimer() - let l:pos = getcurpos()[0:2] + let l:pos = getpos('.')[0:2] " Check the current buffer, line, and column number against the last " recorded position. If the position has actually changed, *then* diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim index 9fc47834..521f0b45 100644 --- a/autoload/ale/definition.vim +++ b/autoload/ale/definition.vim @@ -104,7 +104,7 @@ endfunction function! s:GoToLSPDefinition(linter, options, capability) abort let l:buffer = bufnr('') - let [l:line, l:column] = getcurpos()[1:2] + let [l:line, l:column] = getpos('.')[1:2] let l:column = min([l:column, len(getline(l:line))]) let l:Callback = function( diff --git a/autoload/ale/handlers/rust.vim b/autoload/ale/handlers/rust.vim index c6a4b670..dda6466e 100644 --- a/autoload/ale/handlers/rust.vim +++ b/autoload/ale/handlers/rust.vim @@ -60,7 +60,7 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort \ 'lnum': l:span.line_start, \ 'end_lnum': l:span.line_end, \ 'col': l:span.column_start, - \ 'end_col': l:span.column_end, + \ 'end_col': l:span.column_end-1, \ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label), \ 'type': toupper(l:error.level[0]), \}) diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 6a3f58c9..2af35aa4 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -57,7 +57,7 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort " If the call did __not__ come from balloonexpr... if !get(l:options, 'hover_from_balloonexpr', 0) let l:buffer = bufnr('') - let [l:line, l:column] = getcurpos()[1:2] + let [l:line, l:column] = getpos('.')[1:2] let l:end = len(getline(l:line)) if l:buffer isnot l:options.buffer @@ -174,7 +174,7 @@ endfunction " This function implements the :ALEHover command. function! ale#hover#ShowAtCursor() abort let l:buffer = bufnr('') - let l:pos = getcurpos() + let l:pos = getpos('.') call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {}) endfunction @@ -182,7 +182,7 @@ endfunction " This function implements the :ALEDocumentation command. function! ale#hover#ShowDocumentationAtCursor() abort let l:buffer = bufnr('') - let l:pos = getcurpos() + let l:pos = getpos('.') let l:options = {'show_documentation': 1} call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], l:options) diff --git a/autoload/ale/loclist_jumping.vim b/autoload/ale/loclist_jumping.vim index 6b916227..1d3ef7e5 100644 --- a/autoload/ale/loclist_jumping.vim +++ b/autoload/ale/loclist_jumping.vim @@ -11,7 +11,7 @@ " be returned. function! ale#loclist_jumping#FindNearest(direction, wrap, ...) abort let l:buffer = bufnr('') - let l:pos = getcurpos() + let l:pos = getpos('.') let l:info = get(g:ale_buffer_info, bufnr('%'), {'loclist': []}) " Copy the list and filter to only the items in this buffer. let l:loclist = filter(copy(l:info.loclist), 'v:val.bufnr == l:buffer') diff --git a/autoload/ale/lsp/message.vim b/autoload/ale/lsp/message.vim index dd07685a..646dbd20 100644 --- a/autoload/ale/lsp/message.vim +++ b/autoload/ale/lsp/message.vim @@ -5,7 +5,7 @@ " [is_notification, method_name, params?] " " All functions which accept line and column arguments expect them to be 1-based -" (the same format as being returned by getcurpos() and friends), those then +" (the same format as being returned by getpos() and friends), those then " will be converted to 0-based as specified by LSP. let g:ale_lsp_next_version_id = 1 diff --git a/autoload/ale/preview.vim b/autoload/ale/preview.vim index a94da594..6d58aca9 100644 --- a/autoload/ale/preview.vim +++ b/autoload/ale/preview.vim @@ -71,7 +71,7 @@ endfunction function! s:Open(open_in_tab) abort let l:item_list = get(b:, 'ale_preview_item_list', []) - let l:item = get(l:item_list, getcurpos()[1] - 1, {}) + let l:item = get(l:item_list, getpos('.')[1] - 1, {}) if empty(l:item) return diff --git a/autoload/ale/references.vim b/autoload/ale/references.vim index 14f3cd15..0e88afe2 100644 --- a/autoload/ale/references.vim +++ b/autoload/ale/references.vim @@ -113,7 +113,7 @@ function! ale#references#Find(...) abort endif let l:buffer = bufnr('') - let [l:line, l:column] = getcurpos()[1:2] + let [l:line, l:column] = getpos('.')[1:2] let l:column = min([l:column, len(getline(l:line))]) let l:Callback = function('s:OnReady', [l:line, l:column, l:options]) diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim index 1ed6b0d1..e57307e4 100644 --- a/autoload/ale/util.vim +++ b/autoload/ale/util.vim @@ -470,7 +470,7 @@ endfunction function! ale#util#FindItemAtCursor(buffer) abort let l:info = get(g:ale_buffer_info, a:buffer, {}) let l:loclist = get(l:info, 'loclist', []) - let l:pos = getcurpos() + let l:pos = getpos('.') let l:index = ale#util#BinarySearch(l:loclist, a:buffer, l:pos[1], l:pos[2]) let l:loc = l:index >= 0 ? l:loclist[l:index] : {} diff --git a/autoload/ale/virtualtext.vim b/autoload/ale/virtualtext.vim index c4ce37dd..532427fb 100644 --- a/autoload/ale/virtualtext.vim +++ b/autoload/ale/virtualtext.vim @@ -47,7 +47,6 @@ function! ale#virtualtext#ShowMessage(message, hl_group) abort return endif - let l:cursor_position = getcurpos() let l:line = line('.') let l:buffer = bufnr('') let l:prefix = get(g:, 'ale_virtualtext_prefix', '> ') @@ -117,7 +116,7 @@ function! ale#virtualtext#ShowCursorWarningWithDelay() abort call s:StopCursorTimer() - let l:pos = getcurpos()[0:2] + let l:pos = getpos('.')[0:2] " Check the current buffer, line, and column number against the last " recorded position. If the position has actually changed, *then* diff --git a/doc/ale-rust.txt b/doc/ale-rust.txt index 7510dfbd..3393b9c0 100644 --- a/doc/ale-rust.txt +++ b/doc/ale-rust.txt @@ -172,6 +172,20 @@ g:ale_rust_rls_toolchain *g:ale_rust_rls_toolchain* The `rls` server will only be started once per executable. +g:ale_rust_rls_config *g:ale_rust_rls_config* + *b:ale_rust_rls_config* + Type: |Dictionary| + Default: `{}` + + Dictionary with configuration settings for rls. For example, to force + using clippy as linter: > + { + \ 'rust': { + \ 'clippy_preference': 'on' + \ } + \ } + + =============================================================================== rustc *ale-rust-rustc* diff --git a/doc/ale.txt b/doc/ale.txt index c54aa4b5..eed2c8fb 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -581,8 +581,8 @@ for a function set in the ALE fixer registry. Each function for fixing errors must accept either one argument `(buffer)` or two arguments `(buffer, lines)`, representing the buffer being fixed and the lines to fix. The functions must return either `0`, for changing nothing, a -|List| for new lines to set, or a |Dictionary| for describing a command to be -run in the background. +|List| for new lines to set, a |Dictionary| for describing a command to be +run in the background, or the result of |ale#command#Run()|. Functions receiving a variable number of arguments will not receive the second argument `lines`. Functions should name two arguments if the `lines` argument @@ -612,26 +612,6 @@ are supported for running the commands. A |List| of |String|s must be returned. - `chain_with` An optional key for defining a callback to call next. - - The callback must accept two or three arguments, - `(buffer, output)` or `(buffer, output, input)` . - Functions receiving a variable number of arguments will - only receive the first two values. The `output` argument - will contain the lines of output from the command run. - The `input` argument is the List of lines for the - buffer, after applying any previous fixers. - - The callback must return the same values returned for - any fixer function. This allows fixer functions to be - chained recursively. - - When the command string returned for a fixer is an empty - string, the next command in the chain will still be run. - This allows commands to be skipped, like version checks - that are cached. An empty List will be passed to the - next callback in the chain for the `output`. - `read_buffer` An optional key for disabling reading the buffer. When set to `0`, ALE will not pipe the buffer's data @@ -639,10 +619,7 @@ are supported for running the commands. the buffer is not read when `read_temporary_file` is `1`. - This option defaults to `0` when `chain_with` is defined - as anything other than `v:null`, and defaults to `1` - otherwise. This is so earlier commands in a chain - do not receive the buffer's data by default. + This option defaults to `1`. *ale-fix-configuration* @@ -723,13 +700,13 @@ with |g:ale_completion_excluded_words| or |b:ale_completion_excluded_words|. The |ALEComplete| command can be used to show completion suggestions manually, even when |g:ale_completion_enabled| is set to `0`. - *ale-completion-completopt-bug* + *ale-completion-completeopt-bug* -ALE implements completion as you type by temporarily adjusting |completeopt| -before opening the omnicomplete menu with <C-x><C-o>. In some versions of Vim, -the value set for the option will not be respected. If you experience issues -with Vim automatically inserting text while you type, set the following option -in vimrc, and your issues should go away. > +Automatic completion replaces |completeopt| before opening the omnicomplete +menu with <C-x><C-o>. In some versions of Vim, the value set for the option +will not be respected. If you experience issues with Vim automatically +inserting text while you type, set the following option in vimrc, and your +issues should go away. > set completeopt=menu,menuone,preview,noselect,noinsert < @@ -2938,6 +2915,85 @@ ale#command#CreateFile(buffer) *ale#command#CreateFile()* returning a linter command to run. +ale#command#Run(buffer, command, callback, [options]) *ale#command#Run()* + + Start running a job in the background, and pass the results to the given + callback later. + + This function can be used for computing the results of ALE linter or fixer + functions asynchronously with jobs. `buffer` must match the buffer being + linted or fixed, `command` must be a |String| for a shell command to + execute, `callback` must be defined as a |Funcref| to call later with the + results, and an optional |Dictionary| of `options` can be provided. + + The `callback` will receive the arguments `(buffer, output, metadata)`, + where the `buffer` will match the buffer given to the function, the `output` + will be a `List` of lines of output from the job that was run, and the + `metadata` will be a |Dictionary| with additional information about the job + that was run, including: + + `exit_code` - A |Number| with the exit code for the program that was run. + + The result of this function is either a special |Dictionary| ALE will use + for waiting for the command to finish, or `0` if the job is not started. The + The return value of the `callback` will be used as the eventual result for + whatever value is being given to ALE. For example: > + + function! s:GetCommand(buffer, output, meta) abort + " Do something with a:output here, from the foo command. + + " This is used as the command to run for linting. + return 'final command' + endfunction + + " ... + + 'command': {b -> ale#command#Run(b, 'foo', function('s:GetCommand'))} +< + The result of a callback can also be the result of another call to this + function, so that several commands can be arbitrarily chained together. For + example: > + + function! s:GetAnotherCommand(buffer, output, meta) abort + " We can finally return this command. + return 'last command' + endfunction + + function! s:GetCommand(buffer, output, meta) abort + " We can return another deferred result. + return ale#command#Run( + \ a:buffer, + \ 'second command', + \ function('s:GetAnotherCommand') + \) + endfunction + + " ... + + 'command': {b -> ale#command#Run(b, 'foo', function('s:GetCommand'))} +< + + The following `options` can be provided. + + `output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or `'none`' for + selecting which output streams to read lines from. + + The default is `'stdout'` + + `executable` - An executable for formatting into `%e` in the command. + If this option is not provided, formatting commands with + `%e` will not work. + + `read_buffer` - If set to `1`, the buffer will be piped into the + command. + + The default is `0`. + + `input` - When creating temporary files with `%t` or piping text + into a command `input` can be set to a |List| of text to + use instead of the buffer's text. + + ale#command#EscapeCommandPart(command_part) *ale#command#EscapeCommandPart()* Given a |String|, return a |String| with all `%` characters replaced with @@ -3108,6 +3164,8 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* for computing the executable, accepting a buffer number. + The result can be computed with |ale#command#Run()|. + This value will be used to check if the program requested is installed or not. @@ -3120,50 +3178,12 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* |Funcref| for a function to call for computing the command, accepting a buffer number. + The result can be computed with |ale#command#Run()|. + This command will be fed the lines from the buffer to check, and will produce the lines of output given to the `callback`. - *ale-command-chain* - `command_chain` A |List| of |Dictionary| items defining a series - of commands to be run. At least one |Dictionary| - should be provided. Each Dictionary must contain the - key `callback`, defining a |String| or |Funcref| for - a function returning a |String| for a command to run. - - The callback functions for each command after the - first command in in the chain should accept two - arguments `(buffer, output)`, a buffer number and a - |List| of lines of output from the previous command - in the chain. - - The first callback function in a chain accepts only - a `(buffer)` argument, as there are no previous - commands to run which return `output`. - - If an empty string is returned for a command in a - chain, that command in the chain will be skipped, - and the next function in the chain will be called - immediately instead. If the last command in a chain - returns an empty string, then no linting will be - performed. - - Commands in the chain will all use the - `output_stream` value provided in the root - |Dictionary|. Each command in the chain can also - provide an `output_stream` key to override this value. - See the `output_stream` description for more - information. - - Commands in the chain all behave as if `read_buffer` - is set to `0` by default, except for the last command - in the chain, which uses the value set for - `read_buffer` in the root |Dictionary|. Each command - in the chain can also provide a `read_buffer` key - to override these values. - See the `read_buffer` description for more - information. - `output_stream` A |String| for the output stream the lines of output should be read from for the command which is run. The accepted values are `'stdout'`, `'stderr'`, and @@ -3240,6 +3260,8 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* or a |Funcref| accepting a buffer number and returning the |String|. + The result can be computed with |ale#command#Run()|. + This argument must only be set if the `lsp` argument is set to `'socket'`. @@ -3294,12 +3316,10 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* This will be fed (as JSON) to the LSP in the workspace/didChangeConfiguration command. - Only one of `command` or `command_chain` should be specified. - If temporary files or directories are created for commands run with - `command` or `command_chain`, then these temporary files or directories can - be managed by ALE, for automatic deletion. See |ale#command#ManageFile()| - and |ale#command#ManageDirectory| for more information. + `command`, then these temporary files or directories can be managed by ALE, + for automatic deletion. See |ale#command#ManageFile()| and + |ale#command#ManageDirectory| for more information. *ale-command-format-strings* diff --git a/plugin/ale.vim b/plugin/ale.vim index 1df473c5..ad3d3e56 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -216,7 +216,7 @@ command! -bar ALEDocumentation :call ale#hover#ShowDocumentationAtCursor() " Search for appearances of a symbol, such as a type name or function name. command! -nargs=1 ALESymbolSearch :call ale#symbol#Search(<q-args>) -command! -bar ALEComplete :call ale#completion#AlwaysGetCompletions(0) +command! -bar ALEComplete :call ale#completion#GetCompletions(1) " <Plug> mappings for commands nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return> diff --git a/test/command_callback/java_paths_no_main/src/test/java/com/something/dummy b/test/command_callback/java_paths_no_main/src/test/java/com/something/dummy new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/java_paths_no_main/src/test/java/com/something/dummy diff --git a/test/command_callback/test_javac_command_callback.vader b/test/command_callback/test_javac_command_callback.vader index 2dcb6a1b..a7a928e4 100644 --- a/test/command_callback/test_javac_command_callback.vader +++ b/test/command_callback/test_javac_command_callback.vader @@ -166,3 +166,15 @@ Execute(The javac callback should include src/main/jaxb when available): \ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/jaxb/'), \ ], g:cp_sep)) \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should add -sourcepath even if src/java/main doesn't exist): + call ale#engine#Cleanup(bufnr('')) + call ale#test#SetFilename('java_paths_no_main/src/test/java/com/something/dummy.java') + call ale#engine#InitBufferInfo(bufnr('')) + + AssertLinter 'javac', + \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/java_paths_no_main/src/test/java/'), + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' diff --git a/test/command_callback/test_rust_rls_callbacks.vader b/test/command_callback/test_rust_rls_callbacks.vader index a710161d..ef4735d2 100644 --- a/test/command_callback/test_rust_rls_callbacks.vader +++ b/test/command_callback/test_rust_rls_callbacks.vader @@ -23,3 +23,8 @@ Execute(The project root should be detected correctly): call ale#test#SetFilename('rust-rls-project/test.rs') AssertLSPProject ale#path#Simplify(g:dir . '/rust-rls-project') + +Execute(Should accept configuration settings): + AssertLSPConfig {} + let b:ale_rust_rls_config = {'rust': {'clippy_preference': 'on'}} + AssertLSPConfig {'rust': {'clippy_preference': 'on'}} diff --git a/test/completion/test_completion_events.vader b/test/completion/test_completion_events.vader index 3f0bfa70..d04a8085 100644 --- a/test/completion/test_completion_events.vader +++ b/test/completion/test_completion_events.vader @@ -27,7 +27,7 @@ Before: let g:get_completions_called = 0 " We just want to check if the function is called. - function! ale#completion#GetCompletions() + function! ale#completion#GetCompletions(manual) let g:get_completions_called = 1 endfunction @@ -53,7 +53,7 @@ After: unlet! g:fake_mode unlet! g:get_completions_called unlet! b:ale_old_omnifunc - unlet! b:ale_old_completopt + unlet! b:ale_old_completeopt unlet! b:ale_completion_info unlet! b:ale_completion_response unlet! b:ale_completion_parser @@ -86,7 +86,7 @@ Execute(ale#completion#GetCompletions should not be called when the cursor posit call setpos('.', [bufnr(''), 1, 2, 0]) " We just want to check if the function is called. - function! ale#completion#GetCompletions() + function! ale#completion#GetCompletions(manual) let g:get_completions_called = 1 endfunction @@ -105,7 +105,7 @@ Execute(ale#completion#GetCompletions should not be called if you switch to norm let g:fake_mode = 'n' " We just want to check if the function is called. - function! ale#completion#GetCompletions() + function! ale#completion#GetCompletions(manual) let g:get_completions_called = 1 endfunction @@ -138,7 +138,7 @@ Execute(ale#completion#Show() should remember the completeopt setting and replac call ale#completion#Show('Response', 'Parser') - AssertEqual 'menu', b:ale_old_completopt + AssertEqual 'menu', b:ale_old_completeopt AssertEqual 'menu,menuone,noselect,noinsert', &l:completeopt AssertEqual [], g:feedkeys_calls @@ -150,19 +150,32 @@ Execute(ale#completion#Show() should set the preview option if it's set): call ale#completion#Show('Response', 'Parser') - AssertEqual 'menu,preview', b:ale_old_completopt + AssertEqual 'menu,preview', b:ale_old_completeopt AssertEqual 'menu,menuone,preview,noselect,noinsert', &l:completeopt AssertEqual [], g:feedkeys_calls sleep 1ms AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls +Execute(ale#completion#Show() should not replace the completeopt setting for manual completion): + let b:ale_completion_info = {'manual': 1} + + let &l:completeopt = 'menu,preview' + + call ale#completion#Show('Response', 'Parser') + + Assert !exists('b:ale_old_completeopt') + + AssertEqual [], g:feedkeys_calls + sleep 1ms + AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls + Execute(ale#completion#OmniFunc() should also remember the completeopt setting and replace it): let &l:completeopt = 'menu' call ale#completion#OmniFunc(0, '') - AssertEqual 'menu', b:ale_old_completopt + AssertEqual 'menu', b:ale_old_completeopt AssertEqual 'menu,menuone,noselect,noinsert', &l:completeopt Execute(ale#completion#OmniFunc() should set the preview option if it's set): @@ -170,7 +183,7 @@ Execute(ale#completion#OmniFunc() should set the preview option if it's set): call ale#completion#OmniFunc(0, '') - AssertEqual 'menu,preview', b:ale_old_completopt + AssertEqual 'menu,preview', b:ale_old_completeopt AssertEqual 'menu,menuone,preview,noselect,noinsert', &l:completeopt Execute(ale#completion#Show() should make the correct feedkeys() call): @@ -188,7 +201,7 @@ Execute(ale#completion#Show() shouldn't do anything if you switch back to normal AssertEqual 'menu,preview', &l:completeopt Assert !exists('b:ale_old_omnifunc') - Assert !exists('b:ale_old_completopt') + Assert !exists('b:ale_old_completeopt') Assert !exists('b:ale_completion_response') Assert !exists('b:ale_completion_parser') AssertEqual [], g:feedkeys_calls @@ -209,12 +222,12 @@ Execute(ale#completion#Done() should restore old omnifunc values): Assert !has_key(b:, 'ale_old_omnifunc') Execute(ale#completion#Done() should restore the old completeopt setting): - let b:ale_old_completopt = 'menu' + let b:ale_old_completeopt = 'menu' call ale#completion#Done() AssertEqual 'menu', &l:completeopt - Assert !has_key(b:, 'ale_old_completopt') + Assert !has_key(b:, 'ale_old_completeopt') Execute(ale#completion#Done() should leave settings alone when none were remembered): let &l:omnifunc = 'BazBoz' @@ -236,7 +249,23 @@ Execute(The completion request_id should be reset when queuing again): Execute(b:ale_completion_info should be set up correctly when requesting completions): call setpos('.', [bufnr(''), 3, 14, 0]) - call ale#completion#GetCompletions() + call ale#completion#GetCompletions(0) + + AssertEqual + \ { + \ 'request_id': 0, + \ 'conn_id': 0, + \ 'column': 14, + \ 'line_length': 14, + \ 'line': 3, + \ 'prefix': 'ab', + \ 'manual': 0, + \ }, + \ b:ale_completion_info + +Execute(b:ale_completion_info should be set up correctly when requesting completions): + call setpos('.', [bufnr(''), 3, 14, 0]) + ALEComplete AssertEqual \ { @@ -246,6 +275,7 @@ Execute(b:ale_completion_info should be set up correctly when requesting complet \ 'line_length': 14, \ 'line': 3, \ 'prefix': 'ab', + \ 'manual': 1, \ }, \ b:ale_completion_info @@ -264,7 +294,7 @@ Execute(The correct keybinds should be configured): Execute(Running the normal mode <Plug> keybind should reset the settings): let b:ale_old_omnifunc = 'FooBar' - let b:ale_old_completopt = 'menu' + let b:ale_old_completeopt = 'menu' " We can't run the keybind, but we can call the function. call ale#completion#RestoreCompletionOptions() @@ -272,4 +302,4 @@ Execute(Running the normal mode <Plug> keybind should reset the settings): AssertEqual 'FooBar', &l:omnifunc AssertEqual 'menu', &l:completeopt Assert !has_key(b:, 'ale_old_omnifunc') - Assert !has_key(b:, 'ale_old_completopt') + Assert !has_key(b:, 'ale_old_completeopt') diff --git a/test/completion/test_lsp_completion_messages.vader b/test/completion/test_lsp_completion_messages.vader index c83ad8e1..dce61e36 100644 --- a/test/completion/test_lsp_completion_messages.vader +++ b/test/completion/test_lsp_completion_messages.vader @@ -67,7 +67,7 @@ After: unlet! g:conn_id unlet! g:Callback unlet! b:ale_old_omnifunc - unlet! b:ale_old_completopt + unlet! b:ale_old_completeopt unlet! b:ale_completion_info unlet! b:ale_completion_response unlet! b:ale_completion_parser @@ -102,7 +102,7 @@ Execute(The right message should be sent for the initial tsserver request): " The cursor position needs to match what was saved before. call setpos('.', [bufnr(''), 1, 3, 0]) - call ale#completion#GetCompletions() + call ale#completion#GetCompletions(0) " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) @@ -129,6 +129,7 @@ Execute(The right message should be sent for the initial tsserver request): \ 'request_id': 1, \ 'line': 1, \ 'prefix': 'fo', + \ 'manual': 0, \ }, \ get(b:, 'ale_completion_info', {}) @@ -190,7 +191,7 @@ Execute(The right message should be sent for the initial LSP request): " The cursor position needs to match what was saved before. call setpos('.', [bufnr(''), 1, 5, 0]) - call ale#completion#GetCompletions() + call ale#completion#GetCompletions(0) " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) @@ -233,6 +234,7 @@ Execute(The right message should be sent for the initial LSP request): \ 'request_id': 1, \ 'line': 1, \ 'prefix': 'fo', + \ 'manual': 0, \ 'completion_filter': 'ale#completion#python#CompletionItemFilter', \ }, \ get(b:, 'ale_completion_info', {}) @@ -258,7 +260,7 @@ Execute(Two completion requests shouldn't be sent in a row): " The cursor position needs to match what was saved before. call setpos('.', [bufnr(''), 1, 5, 0]) - call ale#completion#GetCompletions() + call ale#completion#GetCompletions(0) " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) diff --git a/test/handler/test_rust_handler.vader b/test/handler/test_rust_handler.vader index 4764e713..56db9b36 100644 --- a/test/handler/test_rust_handler.vader +++ b/test/handler/test_rust_handler.vader @@ -8,7 +8,7 @@ Execute(The Rust handler should handle rustc output): \ 'end_lnum': 15, \ 'type': 'E', \ 'col': 5, - \ 'end_col': 8, + \ 'end_col': 7, \ 'text': 'expected one of `.`, `;`, `?`, `}`, or an operator, found `for`', \ }, \ { @@ -16,7 +16,7 @@ Execute(The Rust handler should handle rustc output): \ 'end_lnum': 13, \ 'type': 'E', \ 'col': 7, - \ 'end_col': 10, + \ 'end_col': 9, \ 'text': 'no method named `wat` found for type `std::string::String` in the current scope', \ }, \ ], @@ -84,7 +84,7 @@ Execute(The Rust handler should handle cargo output): \ 'end_lnum': 15, \ 'type': 'E', \ 'col': 5, - \ 'end_col': 8, + \ 'end_col': 7, \ 'text': 'expected one of `.`, `;`, `?`, `}`, or an operator, found `for`', \ }, \ { @@ -92,7 +92,7 @@ Execute(The Rust handler should handle cargo output): \ 'end_lnum': 13, \ 'type': 'E', \ 'col': 7, - \ 'end_col': 10, + \ 'end_col': 9, \ 'text': 'no method named `wat` found for type `std::string::String` in the current scope', \ }, \ ], @@ -158,7 +158,7 @@ Execute(The Rust handler should should errors from expansion spans): \ 'end_lnum': 4, \ 'type': 'E', \ 'col': 21, - \ 'end_col': 23, + \ 'end_col': 22, \ 'text': 'mismatched types: expected bool, found integral variable', \ }, \ ], @@ -208,7 +208,7 @@ Execute(The Rust handler should show detailed errors): \ 'end_lnum': 4, \ 'type': 'E', \ 'col': 21, - \ 'end_col': 23, + \ 'end_col': 22, \ 'text': 'mismatched types: expected bool, found integral variable', \ }, \ ], @@ -296,7 +296,7 @@ Execute(The Rust handler should remove secondary spans if set): \ 'lnum': 1, \ 'end_lnum': 1, \ 'type': 'E', - \ 'end_col': 21, + \ 'end_col': 20, \ 'col': 1, \ 'text': 'this function takes 1 parameter but 0 were supplied: defined here', \ }, @@ -304,7 +304,7 @@ Execute(The Rust handler should remove secondary spans if set): \ 'lnum': 1, \ 'end_lnum': 1, \ 'type': 'E', - \ 'end_col': 46, + \ 'end_col': 45, \ 'col': 40, \ 'text': 'this function takes 1 parameter but 0 were supplied: expected 1 parameter', \ }, @@ -371,7 +371,7 @@ Execute(The Rust handler should remove secondary spans if set): \ 'lnum': 1, \ 'end_lnum': 1, \ 'type': 'E', - \ 'end_col': 46, + \ 'end_col': 45, \ 'col': 40, \ 'text': 'this function takes 1 parameter but 0 were supplied: expected 1 parameter', \ }, diff --git a/test/script/custom-linting-rules b/test/script/custom-linting-rules index 77e87db4..981a9459 100755 --- a/test/script/custom-linting-rules +++ b/test/script/custom-linting-rules @@ -106,6 +106,7 @@ check_errors 'let g:ale_\w\+_\w\+_args =' 'Name your option g:ale_<filetype>_<li check_errors 'shellescape(' 'Use ale#Escape instead of shellescape' check_errors 'simplify(' 'Use ale#path#Simplify instead of simplify' check_errors 'tempname(' 'Use ale#util#Tempname instead of tempname' +check_errors 'getcurpos(' "Use getpos('.') instead of getcurpos() if you don't need curswant, to avoid a bug that changes curswant" check_errors "expand(['\"]%" "Use expand('#' . a:buffer . '...') instead. You might get a filename for the wrong buffer." check_errors 'getcwd()' "Do not use getcwd(), as it could run from the wrong buffer. Use expand('#' . a:buffer . ':p:h') instead." check_errors '==#' "Use 'is#' instead of '==#'. 0 ==# 'foobar' is true" diff --git a/test/test_ale_complete_command.vader b/test/test_ale_complete_command.vader deleted file mode 100644 index 11f781c2..00000000 --- a/test/test_ale_complete_command.vader +++ /dev/null @@ -1,26 +0,0 @@ -Before: - function! MockAlwaysGetCompletions() abort - let g:get_completions_called = 0 - let g:always_get_completions_argument = -1 - - function! ale#completion#AlwaysGetCompletions(need_prefix) abort - let g:get_completions_called = 1 - let g:always_get_completions_argument = a:need_prefix - endfunction - endfunction - - call MockAlwaysGetCompletions() - -After: - unlet! g:get_completions_called - unlet! g:always_get_completions_argument - delfunction MockAlwaysGetCompletions - delfunction ale#completion#AlwaysGetCompletions - - runtime autoload/ale/completion.vim - -Execute(ale#completion#AlwaysGetCompletions should be called when ALEComplete is executed): - AssertEqual 0, g:get_completions_called - ALEComplete - AssertEqual 1, g:get_completions_called - AssertEqual 0, g:always_get_completions_argument |