From e5e39a939a7007cfa4c9d922b41dc2bf5a4ec920 Mon Sep 17 00:00:00 2001 From: Kamil Grzywacz Date: Sat, 7 Sep 2019 15:40:35 +0200 Subject: [PATCH 01/20] credo now recognizes umbrella projects Use ale#handlers#elixir#FindMixUmbrellaRoot to determine project root instead of ale#handlers#elixir#FindMixProjectRoot --- ale_linters/elixir/credo.vim | 2 +- test/command_callback/test_elixir_credo.vader | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ale_linters/elixir/credo.vim b/ale_linters/elixir/credo.vim index 317ecab3..7c298502 100644 --- a/ale_linters/elixir/credo.vim +++ b/ale_linters/elixir/credo.vim @@ -46,7 +46,7 @@ function! ale_linters#elixir#credo#GetMode() abort endfunction function! ale_linters#elixir#credo#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) + let l:project_root = ale#handlers#elixir#FindMixUmbrellaRoot(a:buffer) let l:mode = ale_linters#elixir#credo#GetMode() return ale#path#CdString(l:project_root) diff --git a/test/command_callback/test_elixir_credo.vader b/test/command_callback/test_elixir_credo.vader index 1a146db8..3eb88846 100644 --- a/test/command_callback/test_elixir_credo.vader +++ b/test/command_callback/test_elixir_credo.vader @@ -8,6 +8,18 @@ After: call ale#assert#TearDownLinterTest() +Execute(Builds credo command with normal project): + AssertLinter 'mix', + \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) + \ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with umbrella project): + call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinter 'mix', + \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project')) + \ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + Execute(Builds credo command with --strict mode when set to 1): let g:ale_elixir_credo_strict = 1 From 1997a8f7e22a930e3d47b61a7f9ab948d04f2b92 Mon Sep 17 00:00:00 2001 From: Eddie Lebow Date: Sat, 23 Nov 2019 00:06:03 -0500 Subject: [PATCH 02/20] ShellDetect: fall back to filetype if no hashbang Some files lack a hashbang line but still have an unambiguous filetype. For example, the file `.zshrc` has the filetype `zsh`. Augment ale#handlers#sh#GetShellType to fall back to the filetype if no hashbang line can be found. --- autoload/ale/handlers/sh.vim | 19 +++++++++++++------ test/test_shell_detection.vader | 10 ++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/autoload/ale/handlers/sh.vim b/autoload/ale/handlers/sh.vim index 75eaf71f..1e50cb89 100644 --- a/autoload/ale/handlers/sh.vim +++ b/autoload/ale/handlers/sh.vim @@ -4,17 +4,24 @@ function! ale#handlers#sh#GetShellType(buffer) abort let l:bang_line = get(getbufline(a:buffer, 1), 0, '') + let l:command = '' + " Take the shell executable from the hashbang, if we can. if l:bang_line[:1] is# '#!' " Remove options like -e, etc. let l:command = substitute(l:bang_line, ' --\?[a-zA-Z0-9]\+', '', 'g') - - for l:possible_shell in ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'ksh', 'sh'] - if l:command =~# l:possible_shell . '\s*$' - return l:possible_shell - endif - endfor endif + " If we couldn't find a hashbang, try the filetype + if l:command is# '' + let l:command = &filetype + endif + + for l:possible_shell in ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'ksh', 'sh'] + if l:command =~# l:possible_shell . '\s*$' + return l:possible_shell + endif + endfor + return '' endfunction diff --git a/test/test_shell_detection.vader b/test/test_shell_detection.vader index 88ee462d..b0b38aad 100644 --- a/test/test_shell_detection.vader +++ b/test/test_shell_detection.vader @@ -98,6 +98,16 @@ Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1): AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) +Execute(The filetype should be used as the default shell type when there is no hashbang line): + set filetype=zsh + AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr('')) + + set filetype=tcsh + AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr('')) + + set filetype=python + AssertEqual '', ale#handlers#sh#GetShellType(bufnr('')) + Given(A file with /bin/ash): #!/bin/ash From ece229c06f36efdc172ae6d70c73b72a16bb4cdf Mon Sep 17 00:00:00 2001 From: Eddie Lebow Date: Sat, 23 Nov 2019 00:06:41 -0500 Subject: [PATCH 03/20] shell: Make description more accurate The shell linter does more than just bash. --- ale_linters/sh/shell.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/sh/shell.vim b/ale_linters/sh/shell.vim index 171fe64e..73ab3608 100644 --- a/ale_linters/sh/shell.vim +++ b/ale_linters/sh/shell.vim @@ -1,5 +1,5 @@ " Author: w0rp -" Description: Lints sh files using bash -n +" Description: Lints shell files by invoking the shell with -n " Backwards compatibility if exists('g:ale_linters_sh_shell_default_shell') From 0cea55924ba7780c1f17d17e8509160c77d1ab7c Mon Sep 17 00:00:00 2001 From: davidsierradz Date: Thu, 19 Dec 2019 13:11:25 -0500 Subject: [PATCH 04/20] allow passing custom options to markdownlint --- ale_linters/markdown/markdownlint.vim | 13 ++++++++++++- doc/ale-markdown.txt | 11 +++++++++++ doc/ale.txt | 1 + ...est_markdown_markdownlint_command_callback.vader | 13 +++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/command_callback/test_markdown_markdownlint_command_callback.vader diff --git a/ale_linters/markdown/markdownlint.vim b/ale_linters/markdown/markdownlint.vim index e935cbfe..7a293938 100644 --- a/ale_linters/markdown/markdownlint.vim +++ b/ale_linters/markdown/markdownlint.vim @@ -1,11 +1,22 @@ " Author: Ty-Lucas Kelley " Description: Adds support for markdownlint +call ale#Set('markdown_markdownlint_options', '') + +function! ale_linters#markdown#markdownlint#GetCommand(buffer) abort + let l:executable = 'markdownlint' + + let l:options = ale#Var(a:buffer, 'markdown_markdownlint_options') + + return ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') . ' %s' +endfunction + call ale#linter#Define('markdown', { \ 'name': 'markdownlint', \ 'executable': 'markdownlint', \ 'lint_file': 1, \ 'output_stream': 'both', -\ 'command': 'markdownlint %s', +\ 'command': function('ale_linters#markdown#markdownlint#GetCommand'), \ 'callback': 'ale#handlers#markdownlint#Handle' \}) diff --git a/doc/ale-markdown.txt b/doc/ale-markdown.txt index 4e27eb91..99848878 100644 --- a/doc/ale-markdown.txt +++ b/doc/ale-markdown.txt @@ -2,6 +2,17 @@ ALE Markdown Integration *ale-markdown-options* +=============================================================================== +markdownlint *ale-markdown-markdownlint* + +g:ale_markdown_markdownlint_options *g:ale_markdown_markdownlint_options* + *b:ale_markdown_markdownlint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to markdownlint. + + =============================================================================== mdl *ale-markdown-mdl* diff --git a/doc/ale.txt b/doc/ale.txt index 847a9777..de46d7ac 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2425,6 +2425,7 @@ documented in additional help files. luac..................................|ale-lua-luac| luacheck..............................|ale-lua-luacheck| markdown................................|ale-markdown-options| + markdownlint..........................|ale-markdown-markdownlint| mdl...................................|ale-markdown-mdl| prettier..............................|ale-markdown-prettier| remark-lint...........................|ale-markdown-remark-lint| diff --git a/test/command_callback/test_markdown_markdownlint_command_callback.vader b/test/command_callback/test_markdown_markdownlint_command_callback.vader new file mode 100644 index 00000000..12766cfd --- /dev/null +++ b/test/command_callback/test_markdown_markdownlint_command_callback.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('markdown', 'markdownlint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'markdownlint', ale#Escape('markdownlint') . ' %s' + +Execute(The options should be configurable): + let g:ale_markdown_markdownlint_options = '--config ~/custom/.markdownlintrc' + + AssertLinter 'markdownlint', ale#Escape('markdownlint') . ' --config ~/custom/.markdownlintrc %s' From c207d6a550916f4d34a41711c64024251466fea5 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Thu, 12 Mar 2020 16:00:30 +0900 Subject: [PATCH 05/20] Fix 2816 - Standard fix does not work. The standard linter --fix fails if the file being input is not relative to the project root (https://github.com/standard/standard/issues/1384). This MR attempts to fix this by changing the command so the input file is relative to the project root and the output is to a temporary file. Preliminary tests with toy javascript projects seem to indicate this works fine. --- autoload/ale/fixers/standard.vim | 2 +- test/fixers/test_standard_fixer_callback.vader | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/autoload/ale/fixers/standard.vim b/autoload/ale/fixers/standard.vim index cffa9f9d..46decebf 100644 --- a/autoload/ale/fixers/standard.vim +++ b/autoload/ale/fixers/standard.vim @@ -27,7 +27,7 @@ function! ale#fixers#standard#Fix(buffer) abort return { \ 'command': ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' --fix %t', + \ . ' --fix --stdin < %s > %t', \ 'read_temporary_file': 1, \} endfunction diff --git a/test/fixers/test_standard_fixer_callback.vader b/test/fixers/test_standard_fixer_callback.vader index db9f20f6..f5e9c487 100644 --- a/test/fixers/test_standard_fixer_callback.vader +++ b/test/fixers/test_standard_fixer_callback.vader @@ -15,7 +15,7 @@ Execute(The executable path should be correct): \ 'read_temporary_file': 1, \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/standard/bin/cmd.js')) - \ . ' --fix %t', + \ . ' --fix --stdin < %s > %t', \ }, \ ale#fixers#standard#Fix(bufnr('')) @@ -26,6 +26,6 @@ Execute(Custom options should be supported): AssertEqual \ { \ 'read_temporary_file': 1, - \ 'command': ale#Escape('standard') . ' --foo-bar --fix %t', + \ 'command': ale#Escape('standard') . ' --foo-bar --fix --stdin < %s > %t', \ }, \ ale#fixers#standard#Fix(bufnr('')) From fc6677d40565f4c84730a7cfb0af186f183be031 Mon Sep 17 00:00:00 2001 From: Alex Wang Date: Tue, 17 Mar 2020 18:00:47 -0400 Subject: [PATCH 06/20] Avoid overriding parsed C/C++ -std=* flag ALE appends flags from {c,cpp}_{clang,gcc}_options after those found by parsing compile_commands.json or Makefile output. If -std=* flags are present in both the ALE flags and parsed flags, the last one present (i.e., ALE's -std=* flag) will determine the mode the compiler works in. This can result in errors showing up in vim but not in the actual build or vice-versa. For example, say you have foo.cpp: #include int main() { return std::is_same_v; } If cpp_clang_options contains -std=c++17 and -std=c++14 is parsed from compile_commands.json, then ALE would end up running something like: clang++ -S -x c++ -fsyntax-only -std=c++14 -std=c++17 - < foo.cpp This would result in no errors showing up in Vim, but the actual build would fail with: :3:14: error: no template named 'is_same_v' in namespace 'std'; did you mean 'is_same'? return std::is_same_v; ~~~~~^~~~~~~~~ is_same /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/type_traits:872:61: note: 'is_same' declared here template struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {}; ^ :3:35: error: expected '(' for function-style cast or type construction return std::is_same_v; ~~~~~~~~~~~~~~~~~~~~~~~~~~^ 2 errors generated. as the actual build would not have the -std=c++17 flag added by ALE. If cpp_clang_options contains -std=c++14 and -std=c++17 is parsed from compile_commands.json, then the opposite problem would occur. ALE would end up running something like: clang++ -S -x c++ -fsyntax-only -std=c++17 -std=c++14 - < foo.cpp and would show an error on line 3 of foo.cpp: [clang] No template named 'is_same_v' in namespace 'std'; did you mean 'is_same'? (fix available) The actual build, on the other hand, would succeed without any complaints. Removing -std=* from ALE's flags if it is already present in the parsed flags ensures that the wrong -std=* flag is not used. An alternative would have been to switch the order in which parsed flags and ALE flags were concatenated when producing the command to execute, but that could prevent a user from intentionally using ALE's flags to override some other flags, e.g. -W* flags to enable/disable warnings in a project whose flags are not under the developer's control. -std=* flags are also present in cuda/nvcc.vim, objc/clang.vim, objcpp/clang.vim, and vhdl/ghdl.vim, but none of those linters appear to parse compile_commands.json or `make` output. --- ale_linters/c/clang.vim | 11 ++++++++++- ale_linters/c/gcc.vim | 11 ++++++++++- ale_linters/cpp/clang.vim | 11 ++++++++++- ale_linters/cpp/gcc.vim | 11 ++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/ale_linters/c/clang.vim b/ale_linters/c/clang.vim index 681101fc..84c105de 100644 --- a/ale_linters/c/clang.vim +++ b/ale_linters/c/clang.vim @@ -6,13 +6,22 @@ call ale#Set('c_clang_options', '-std=c11 -Wall') function! ale_linters#c#clang#GetCommand(buffer, output) abort let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:ale_flags = ale#Var(a:buffer, 'c_clang_options') + + if l:cflags =~# '-std=' + let l:ale_flags = substitute( + \ l:ale_flags, + \ '-std=\(c\|gnu\)[0-9]\{2\}', + \ '', + \ 'g') + endif " -iquote with the directory the file is in makes #include work for " headers in the same directory. return '%e -S -x c -fsyntax-only' \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ale#Pad(l:cflags) - \ . ale#Pad(ale#Var(a:buffer, 'c_clang_options')) . ' -' + \ . ale#Pad(l:ale_flags) . ' -' endfunction call ale#linter#Define('c', { diff --git a/ale_linters/c/gcc.vim b/ale_linters/c/gcc.vim index 1df1018e..252285a3 100644 --- a/ale_linters/c/gcc.vim +++ b/ale_linters/c/gcc.vim @@ -6,6 +6,15 @@ call ale#Set('c_gcc_options', '-std=c11 -Wall') function! ale_linters#c#gcc#GetCommand(buffer, output) abort let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:ale_flags = ale#Var(a:buffer, 'c_gcc_options') + + if l:cflags =~# '-std=' + let l:ale_flags = substitute( + \ l:ale_flags, + \ '-std=\(c\|gnu\)[0-9]\{2\}', + \ '', + \ 'g') + endif " -iquote with the directory the file is in makes #include work for " headers in the same directory. @@ -16,7 +25,7 @@ function! ale_linters#c#gcc#GetCommand(buffer, output) abort \ . ' -o ' . g:ale#util#nul_file \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ale#Pad(l:cflags) - \ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -' + \ . ale#Pad(l:ale_flags) . ' -' endfunction call ale#linter#Define('c', { diff --git a/ale_linters/cpp/clang.vim b/ale_linters/cpp/clang.vim index e48291eb..d93638ec 100644 --- a/ale_linters/cpp/clang.vim +++ b/ale_linters/cpp/clang.vim @@ -6,13 +6,22 @@ call ale#Set('cpp_clang_options', '-std=c++14 -Wall') function! ale_linters#cpp#clang#GetCommand(buffer, output) abort let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:ale_flags = ale#Var(a:buffer, 'cpp_clang_options') + + if l:cflags =~# '-std=' + let l:ale_flags = substitute( + \ l:ale_flags, + \ '-std=\(c\|gnu\)++[0-9]\{2\}', + \ '', + \ 'g') + endif " -iquote with the directory the file is in makes #include work for " headers in the same directory. return '%e -S -x c++ -fsyntax-only' \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ale#Pad(l:cflags) - \ . ale#Pad(ale#Var(a:buffer, 'cpp_clang_options')) . ' -' + \ . ale#Pad(l:ale_flags) . ' -' endfunction call ale#linter#Define('cpp', { diff --git a/ale_linters/cpp/gcc.vim b/ale_linters/cpp/gcc.vim index 108d6d70..89c2d358 100644 --- a/ale_linters/cpp/gcc.vim +++ b/ale_linters/cpp/gcc.vim @@ -6,6 +6,15 @@ call ale#Set('cpp_gcc_options', '-std=c++14 -Wall') function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:ale_flags = ale#Var(a:buffer, 'cpp_gcc_options') + + if l:cflags =~# '-std=' + let l:ale_flags = substitute( + \ l:ale_flags, + \ '-std=\(c\|gnu\)++[0-9]\{2\}', + \ '', + \ 'g') + endif " -iquote with the directory the file is in makes #include work for " headers in the same directory. @@ -16,7 +25,7 @@ function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort \ . ' -o ' . g:ale#util#nul_file \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ale#Pad(l:cflags) - \ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -' + \ . ale#Pad(l:ale_flags) . ' -' endfunction call ale#linter#Define('cpp', { From 2548763d04568823c4ef240f7f115adbb1dcfca2 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 11 Feb 2020 15:57:58 +0100 Subject: [PATCH 07/20] Add Apple's swift-format as a linter --- ale_linters/swift/swiftformat.vim | 62 +++++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + supported-tools.md | 1 + ..._swift_swiftformat_command_callbacks.vader | 25 ++++++++ test/handler/test_swiftformat_handler.vader | 28 +++++++++ 5 files changed, 117 insertions(+) create mode 100644 ale_linters/swift/swiftformat.vim create mode 100644 test/command_callback/test_swift_swiftformat_command_callbacks.vader create mode 100644 test/handler/test_swiftformat_handler.vader diff --git a/ale_linters/swift/swiftformat.vim b/ale_linters/swift/swiftformat.vim new file mode 100644 index 00000000..2504511a --- /dev/null +++ b/ale_linters/swift/swiftformat.vim @@ -0,0 +1,62 @@ +" Author: Klaas Pieter Annema +" Description: Support for swift-format https://github.com/apple/swift-format + +let s:default_executable = 'swift-format' +call ale#Set('swift_swiftformat_executable', s:default_executable) + +function! ale_linters#swift#swiftformat#UseSwift(buffer) abort + let l:swift_config = ale#path#FindNearestFile(a:buffer, 'Package.swift') + let l:executable = ale#Var(a:buffer, 'swift_swiftformat_executable') + + return !empty(l:swift_config) && l:executable is# s:default_executable +endfunction + +function! ale_linters#swift#swiftformat#GetExecutable(buffer) abort + if ale_linters#swift#swiftformat#UseSwift(a:buffer) + return 'swift' + endif + + return ale#Var(a:buffer, 'swift_swiftformat_executable') +endfunction + +function! ale_linters#swift#swiftformat#GetCommand(buffer) abort + let l:executable = ale_linters#swift#swiftformat#GetExecutable(a:buffer) + let l:args = '--mode lint %t' + + if ale_linters#swift#swiftformat#UseSwift(a:buffer) + let l:args = 'run swift-format' . ' ' . l:args + endif + + return ale#Escape(l:executable) . ' ' . l:args +endfunction + +function! ale_linters#swift#swiftformat#Handle(buffer, lines) abort + " Matches lines of the following pattern: + " + " Sources/main.swift:4:21: warning: [DoNotUseSemicolons]: remove ';' and move the next statement to the new line + " Sources/main.swift:3:12: warning: [Spacing]: remove 1 space + let l:pattern = '\v^.*:(\d+):(\d+): (\S+) \[(\S+)\]: (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \ 'code': l:match[4], + \ 'text': l:match[5], + \}) + endfor + + return l:output +endfunction + + +call ale#linter#Define('swift', { +\ 'name': 'swift-format', +\ 'executable': function('ale_linters#swift#swiftformat#GetExecutable'), +\ 'command': function('ale_linters#swift#swiftformat#GetCommand'), +\ 'output_stream': 'stderr', +\ 'language': 'swift', +\ 'callback': 'ale_linters#swift#swiftformat#Handle' +\}) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 636985fb..6a695bcc 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -445,6 +445,7 @@ Notes: * Swift * `sourcekit-lsp` * `swiftformat` + * `swift-format` * `swiftlint` * Tcl * `nagelfar`!! diff --git a/supported-tools.md b/supported-tools.md index d5c0c9d4..b1a81308 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -454,6 +454,7 @@ formatting. * Swift * [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) * [swiftformat](https://github.com/nicklockwood/SwiftFormat) + * [swift-format](https://github.com/apple/swift-format) * [swiftlint](https://github.com/realm/SwiftLint) * Tcl * [nagelfar](http://nagelfar.sourceforge.net) :floppy_disk: diff --git a/test/command_callback/test_swift_swiftformat_command_callbacks.vader b/test/command_callback/test_swift_swiftformat_command_callbacks.vader new file mode 100644 index 00000000..7be20bf7 --- /dev/null +++ b/test/command_callback/test_swift_swiftformat_command_callbacks.vader @@ -0,0 +1,25 @@ +Before: + call ale#assert#SetUpLinterTest('swift', 'swiftformat') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should use default command when not in a swift package): + call ale#test#SetFilename('../swift-test-files/non-swift-package-project/src/folder/dummy.swift') + + AssertLinter 'swift-format', + \ ale#Escape('swift-format') . ' --mode lint %t' + +Execute(Should use swift run when in a swift package): + call ale#test#SetFilename('../swift-test-files/swift-package-project/src/folder/dummy.swift') + + AssertLinter 'swift', + \ ale#Escape('swift') . ' run swift-format --mode lint %t' + +Execute(Should let users configure a global executable and override local paths): + call ale#test#SetFilename('../swift-test-files/swift-package-project/src/folder/dummy.swift') + + let g:ale_swift_swiftformat_executable = '/path/to/custom/swift-format' + + AssertLinter '/path/to/custom/swift-format', + \ ale#Escape('/path/to/custom/swift-format') . ' --mode lint %t' diff --git a/test/handler/test_swiftformat_handler.vader b/test/handler/test_swiftformat_handler.vader new file mode 100644 index 00000000..3dcc4f1a --- /dev/null +++ b/test/handler/test_swiftformat_handler.vader @@ -0,0 +1,28 @@ +Before: + runtime ale_linters/swift/swiftformat.vim + +After: + call ale#linter#Reset() + +Execute(The swiftformat handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 21, + \ 'type': 'W', + \ 'code': 'DoNotUseSemicolons', + \ 'text': 'remove '';'' and move the next statement to the new line', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 12, + \ 'type': 'W', + \ 'code': 'Spacing', + \ 'text': 'remove 1 space' + \ }, + \ ], + \ ale_linters#swift#swiftformat#Handle(bufnr(''), [ + \ 'Sources/main.swift:4:21: warning: [DoNotUseSemicolons]: remove '';'' and move the next statement to the new line', + \ 'Sources/main.swift:3:12: warning: [Spacing]: remove 1 space', + \ ]) From b20931571484108d1ec29eaab5b731e754649664 Mon Sep 17 00:00:00 2001 From: Stephen Robinson Date: Thu, 2 Apr 2020 15:49:03 -0700 Subject: [PATCH 08/20] Fixes #3092 - Implement loading `@file` c arguments --- autoload/ale/c.vim | 50 ++++++++++++++++++- test/test_c_flag_parsing.vader | 11 ++++ test/test_c_projects/makefile_project/args | 3 ++ .../makefile_project/subdir/args | 1 + 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/test_c_projects/makefile_project/args create mode 100644 test/test_c_projects/makefile_project/subdir/args diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index 9b428700..e8212dcd 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -68,10 +68,58 @@ function! ale#c#ShellSplit(line) abort return l:args endfunction +" Takes the path prefix and a list of cflags and expands @file arguments to +" the contents of the file. +" +" @file arguments are command line arguments recognised by gcc and clang. For +" instance, if @./path/to/file was given to gcc, it would load .path/to/file +" and use the contents of that file as arguments. +function! ale#c#ExpandAtArgs(path_prefix, raw_split_lines) abort + let l:out_lines = [] + + for l:option in a:raw_split_lines + if stridx(l:option, '@') == 0 + " This is an argument specifying a location of a file containing other arguments + let l:path = join(split(l:option, '\zs')[1:], '') + + " Make path absolute + if stridx(l:path, s:sep) != 0 && stridx(l:path, '/') != 0 + let l:rel_path = substitute(l:path, '"', '', 'g') + let l:rel_path = substitute(l:rel_path, '''', '', 'g') + let l:path = a:path_prefix . s:sep . l:rel_path + endif + + " Read the file and add all the arguments + try + let l:additional_args = readfile(l:path) + catch + continue " All we can really do is skip this argument + endtry + + let l:file_lines = [] + + for l:line in l:additional_args + let l:file_lines += ale#c#ShellSplit(l:line) + endfor + + " @file arguments can include other @file arguments, so we must + " recurse. + let l:out_lines += ale#c#ExpandAtArgs(a:path_prefix, l:file_lines) + else + " This is not an @file argument, so don't touch it. + let l:out_lines += [l:option] + endif + endfor + + return l:out_lines +endfunction + function! ale#c#ParseCFlags(path_prefix, cflag_line) abort let l:cflags_list = [] - let l:split_lines = ale#c#ShellSplit(a:cflag_line) + let l:raw_split_lines = ale#c#ShellSplit(a:cflag_line) + " Expand @file arguments now before parsing + let l:split_lines = ale#c#ExpandAtArgs(a:path_prefix, l:raw_split_lines) let l:option_index = 0 while l:option_index < len(l:split_lines) diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index 8ae6f9dc..dff19aa3 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -366,3 +366,14 @@ Execute(CFlags we dont want to pass): \ 'gcc -Wl,option -Wa,option -Wp,option filename.c somelib.a ' \ . '-fdump-file=name -fdiagnostics-arg -fno-show-column' \ ) + +Execute(Expanding @file in CFlags): + AssertEqual + \ '-DARGS1 -DARGS2 -O2', + \ ale#c#ParseCFlags( + \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ 'gcc' + \ . ' -g' + \ . ' @./args' + \ . ' -O2', + \ ) diff --git a/test/test_c_projects/makefile_project/args b/test/test_c_projects/makefile_project/args new file mode 100644 index 00000000..ccaf82ad --- /dev/null +++ b/test/test_c_projects/makefile_project/args @@ -0,0 +1,3 @@ +foolib.a +-DARGS1 +@subdir/args diff --git a/test/test_c_projects/makefile_project/subdir/args b/test/test_c_projects/makefile_project/subdir/args new file mode 100644 index 00000000..3fe9c3fe --- /dev/null +++ b/test/test_c_projects/makefile_project/subdir/args @@ -0,0 +1 @@ +-DARGS2 From c136061b3f4eeabbbe45ab25b75138aaec1f003d Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Thu, 9 Jul 2020 10:46:33 +0900 Subject: [PATCH 09/20] Enable languagetool for asciidoctor files. --- ale_linters/asciidoc/languagetool.vim | 5 +++++ doc/ale-supported-languages-and-tools.txt | 1 + supported-tools.md | 1 + 3 files changed, 7 insertions(+) create mode 100644 ale_linters/asciidoc/languagetool.vim diff --git a/ale_linters/asciidoc/languagetool.vim b/ale_linters/asciidoc/languagetool.vim new file mode 100644 index 00000000..f16df6c0 --- /dev/null +++ b/ale_linters/asciidoc/languagetool.vim @@ -0,0 +1,5 @@ +" Author: Horacio Sanson (hsanson [ät] gmail.com) +" Description: languagetool for asciidoc files, copied from markdown. + + +call ale#handlers#languagetool#DefineLinter('asciidoctor') diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 45252294..7399041b 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -21,6 +21,7 @@ Notes: * `drafter` * AsciiDoc * `alex`!! + * `languagetool`!! * `proselint` * `redpen` * `textlint` diff --git a/supported-tools.md b/supported-tools.md index 7d2f5287..6ef67f29 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -30,6 +30,7 @@ formatting. * [drafter](https://github.com/apiaryio/drafter) * AsciiDoc * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [languagetool](https://languagetool.org/) :floppy_disk: * [proselint](http://proselint.com/) * [redpen](http://redpen.cc/) * [textlint](https://textlint.github.io/) From 5c778e1ae752163a849609318ace6c3c6a37d6f7 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 16 Aug 2020 21:19:07 +0100 Subject: [PATCH 10/20] Make it easier to run tests locally Certain tests could break if you ran them separately from other tests. They have been patched. `run-tests` now has a `--fast` option which runs tests with only the fastest Vim version ALE tests with, and the custom checks. --- run-tests | 8 ++++++++ test/fix/test_ale_fix.vader | 2 ++ test/fixers/test_eslint_fixer_callback.vader | 4 ++++ test/fixers/test_prettier_eslint_fixer.callback.vader | 3 +++ test/fixers/test_prettier_fixer_callback.vader | 3 +++ test/handler/test_glslang_handler.vader | 3 +++ test/handler/test_standard_handler.vader | 8 ++++++++ test/lsp/test_lsp_command_formatting.vader | 6 ++++++ test/sign/test_linting_sets_signs.vader | 2 ++ test/sign/test_sign_placement.vader | 2 ++ 10 files changed, 41 insertions(+) diff --git a/run-tests b/run-tests index c71f90d1..1d452a72 100755 --- a/run-tests +++ b/run-tests @@ -83,6 +83,13 @@ while [ $# -ne 0 ]; do run_neovim_03_tests=0 shift ;; + --fast) + run_vim_80_tests=0 + run_vim_81_tests=0 + run_neovim_02_tests=0 + run_neovim_03_tests=1 + shift + ;; --help) echo 'Usage: ./run-tests [OPTION]... [FILE]...' echo @@ -99,6 +106,7 @@ while [ $# -ne 0 ]; do echo ' --vim-80-only Run tests only for Vim 8.0' echo ' --vim-81-only Run tests only for Vim 8.1' echo ' --linters-only Run only Vint and custom checks' + echo ' --fast Run only the fastest Vim and custom checks' echo ' --help Show this help text' echo ' -- Stop parsing options after this' exit 0 diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader index c3dd20e4..6081f4e2 100644 --- a/test/fix/test_ale_fix.vader +++ b/test/fix/test_ale_fix.vader @@ -5,12 +5,14 @@ Before: Save g:ale_fix_on_save Save g:ale_lint_on_save Save g:ale_echo_cursor + Save g:ale_command_wrapper silent! cd /testplugin/test/fix unlet! b:ale_lint_on_save let g:ale_enabled = 0 let g:ale_echo_cursor = 0 + let g:ale_command_wrapper = '' let g:ale_run_synchronously = 1 let g:ale_set_lists_synchronously = 1 let g:ale_fix_buffer_data = {} diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader index 400267ac..50fc6672 100644 --- a/test/fixers/test_eslint_fixer_callback.vader +++ b/test/fixers/test_eslint_fixer_callback.vader @@ -1,7 +1,11 @@ Before: call ale#assert#SetUpFixerTest('javascript', 'eslint') + Save g:ale_command_wrapper + runtime autoload/ale/handlers/eslint.vim + let g:ale_command_wrapper = '' + After: call ale#assert#TearDownFixerTest() diff --git a/test/fixers/test_prettier_eslint_fixer.callback.vader b/test/fixers/test_prettier_eslint_fixer.callback.vader index 90e11672..f7bb3c61 100644 --- a/test/fixers/test_prettier_eslint_fixer.callback.vader +++ b/test/fixers/test_prettier_eslint_fixer.callback.vader @@ -1,5 +1,8 @@ Before: call ale#assert#SetUpFixerTest('javascript', 'prettier_eslint') + Save g:ale_command_wrapper + + let g:ale_command_wrapper = '' After: call ale#assert#TearDownFixerTest() diff --git a/test/fixers/test_prettier_fixer_callback.vader b/test/fixers/test_prettier_fixer_callback.vader index 062ae8cf..1087a160 100644 --- a/test/fixers/test_prettier_fixer_callback.vader +++ b/test/fixers/test_prettier_fixer_callback.vader @@ -1,5 +1,8 @@ Before: call ale#assert#SetUpFixerTest('javascript', 'prettier') + Save g:ale_command_wrapper + + let g:ale_command_wrapper = '' silent cd .. silent cd command_callback diff --git a/test/handler/test_glslang_handler.vader b/test/handler/test_glslang_handler.vader index d51c9852..6d3a7999 100644 --- a/test/handler/test_glslang_handler.vader +++ b/test/handler/test_glslang_handler.vader @@ -1,3 +1,6 @@ +Before: + runtime ale_linters/glsl/glslang.vim + Execute(The glsl glslang handler should parse lines correctly): AssertEqual \ [ diff --git a/test/handler/test_standard_handler.vader b/test/handler/test_standard_handler.vader index 59ebe531..31e3a36b 100644 --- a/test/handler/test_standard_handler.vader +++ b/test/handler/test_standard_handler.vader @@ -1,3 +1,11 @@ +Before: + Save g:ale_javascript_eslint_suppress_eslintignore + + let g:ale_javascript_eslint_suppress_eslintignore = 0 + +After: + Restore + Execute(The standard handler should parse lines correctly): AssertEqual \ [ diff --git a/test/lsp/test_lsp_command_formatting.vader b/test/lsp/test_lsp_command_formatting.vader index ec3b4120..2c1e8788 100644 --- a/test/lsp/test_lsp_command_formatting.vader +++ b/test/lsp/test_lsp_command_formatting.vader @@ -1,6 +1,10 @@ Before: + Save g:ale_command_wrapper + runtime autoload/ale/lsp.vim + let g:ale_command_wrapper = '' + let g:args = [] " Mock the StartProgram function so we can just capture the arguments. @@ -9,6 +13,8 @@ Before: endfunction After: + Restore + unlet! g:args runtime autoload/ale/lsp.vim diff --git a/test/sign/test_linting_sets_signs.vader b/test/sign/test_linting_sets_signs.vader index 1d1f9802..1624449a 100644 --- a/test/sign/test_linting_sets_signs.vader +++ b/test/sign/test_linting_sets_signs.vader @@ -10,7 +10,9 @@ Before: Save g:ale_set_loclist Save g:ale_set_quickfix Save g:ale_set_signs + Save g:ale_command_wrapper + let g:ale_command_wrapper = '' let g:ale_buffer_info = {} let g:ale_run_synchronously = 1 unlet! g:ale_run_synchronously_callbacks diff --git a/test/sign/test_sign_placement.vader b/test/sign/test_sign_placement.vader index d8d05b28..7b80d83c 100644 --- a/test/sign/test_sign_placement.vader +++ b/test/sign/test_sign_placement.vader @@ -6,7 +6,9 @@ Before: Save g:ale_set_loclist Save g:ale_set_quickfix Save g:ale_set_signs + Save g:ale_command_wrapper + let g:ale_command_wrapper = '' let g:ale_buffer_info = {} let g:ale_run_synchronously = 1 let g:ale_set_signs = 1 From d5c1d842307a4c916905d5160544cfe152a16ee0 Mon Sep 17 00:00:00 2001 From: blyoa Date: Mon, 17 Aug 2020 18:14:38 +0900 Subject: [PATCH 11/20] Add remark-lint for a markdown fixer (#2836) --- autoload/ale/fix/registry.vim | 5 ++++ autoload/ale/fixers/remark_lint.vim | 24 +++++++++++++++++++ .../test_remark_lint_fixer_callback.vader | 24 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 autoload/ale/fixers/remark_lint.vim create mode 100644 test/fixers/test_remark_lint_fixer_callback.vader diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 02b02699..94476ca9 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -365,6 +365,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['nix'], \ 'description': 'A formatter for Nix code', \ }, +\ 'remark-lint': { +\ 'function': 'ale#fixers#remark_lint#Fix', +\ 'suggested_filetypes': ['markdown'], +\ 'description': 'Fix markdown files with remark-lint', +\ }, \ 'html-beautify': { \ 'function': 'ale#fixers#html_beautify#Fix', \ 'suggested_filetypes': ['html', 'htmldjango'], diff --git a/autoload/ale/fixers/remark_lint.vim b/autoload/ale/fixers/remark_lint.vim new file mode 100644 index 00000000..3ce442f3 --- /dev/null +++ b/autoload/ale/fixers/remark_lint.vim @@ -0,0 +1,24 @@ +" Author: blyoa +" Description: Fixing files with remark-lint. + +call ale#Set('markdown_remark_lint_executable', 'remark') +call ale#Set('markdown_remark_lint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('markdown_remark_lint_options', '') + +function! ale#fixers#remark_lint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'markdown_remark_lint', [ + \ 'node_modules/remark-cli/cli.js', + \ 'node_modules/.bin/remark', + \]) +endfunction + +function! ale#fixers#remark_lint#Fix(buffer) abort + let l:executable = ale#fixers#remark_lint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'markdown_remark_lint_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : ''), + \} +endfunction + diff --git a/test/fixers/test_remark_lint_fixer_callback.vader b/test/fixers/test_remark_lint_fixer_callback.vader new file mode 100644 index 00000000..5e2e342d --- /dev/null +++ b/test/fixers/test_remark_lint_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_markdown_remark_lint_executable + Save g:ale_markdown_remark_lint_options + +After: + Restore + +Execute(The remark callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('remark') + \ }, + \ ale#fixers#remark_lint#Fix(bufnr('')) + +Execute(The remark executable and options should be configurable): + let g:ale_markdown_remark_lint_executable = '/path/to/remark' + let g:ale_markdown_remark_lint_options = '-h' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/remark') + \ . ' -h', + \ }, + \ ale#fixers#remark_lint#Fix(bufnr('')) From cfda549056c4b85fba9e2f10ecb502c8a18d6011 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 17 Aug 2020 10:20:41 +0100 Subject: [PATCH 12/20] Tell stale bot to wait longer before closing PRs --- .github/stale.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/stale.yml b/.github/stale.yml index e9cda3d9..3a5a354b 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,9 +1,10 @@ --- -# This configuration closes stale PRs after 30 days. +# This configuration closes stale PRs after 28 + 7 days. +# That's 4 weeks until stale bot complains, and a week until it closes a PR. # Issues in ALE are never, ever stale. They are either resolved or not. only: pulls daysUntilStale: 28 -daysUntilClose: 2 +daysUntilClose: 7 exemptLabels: [] staleLabel: stale markComment: > From 4df352eee585cf50edb208aea713fe1a67ac4094 Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 18 Aug 2020 01:48:07 +0100 Subject: [PATCH 13/20] Fix #3294 - Fix hover off by 1, handle LSP server crashes --- autoload/ale/hover.vim | 5 ++++- autoload/ale/lsp.vim | 4 ++++ test/lsp/test_lsp_startup.vader | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 168ff424..38b4b866 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -264,7 +264,10 @@ function! s:OnReady(line, column, opt, linter, lsp_details) abort " hover position probably won't make sense. call ale#lsp#NotifyForChanges(l:id, l:buffer) - let l:column = min([a:column, len(getbufline(l:buffer, a:line)[0])]) + let l:column = max([ + \ min([a:column, len(getbufline(l:buffer, a:line)[0])]), + \ 1, + \]) let l:message = ale#lsp#message#Hover(l:buffer, a:line, l:column) endif diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim index ae8fd51d..7d99e9d2 100644 --- a/autoload/ale/lsp.vim +++ b/autoload/ale/lsp.vim @@ -64,6 +64,9 @@ endfunction " Used only in tests. function! ale#lsp#GetConnections() abort + " This command will throw from the sandbox. + let &l:equalprg=&l:equalprg + return s:connections endfunction @@ -449,6 +452,7 @@ function! ale#lsp#StartProgram(conn_id, executable, command) abort endif if l:started && !l:conn.is_tsserver + let l:conn.initialized = 0 call s:SendInitMessage(l:conn) endif diff --git a/test/lsp/test_lsp_startup.vader b/test/lsp/test_lsp_startup.vader index c29690bf..cd9b59dd 100644 --- a/test/lsp/test_lsp_startup.vader +++ b/test/lsp/test_lsp_startup.vader @@ -422,3 +422,13 @@ Execute(Deferred addresses should be handled correctly): Assert Start() call ale#test#FlushJobs() call AssertInitSuccess('foo', 'localhost:1234', 'foobar', '/foo/bar', '') + +Execute(Servers that have crashed should be restarted): + call ale#lsp#Register('foo', '/foo/bar', {}) + call extend(ale#lsp#GetConnections()['foo:/foo/bar'], {'initialized': 1}) + + " Starting the program again should reset initialized to `0`. + call ale#lsp#StartProgram('foo:/foo/bar', 'foobar', 'foobar --start') + + AssertEqual 0, ale#lsp#GetConnections()['foo:/foo/bar']['initialized'] + AssertEqual ['initialize'], map(PopMessages(), 'v:val[''method'']') From 5eda1df0a96e691ebf24e5d8a3585c2feb2a48a3 Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 18 Aug 2020 23:03:43 +0100 Subject: [PATCH 14/20] Remove features deprecated in previous versions --- ale_linters/ocaml/ols.vim | 2 +- ale_linters/reason/ols.vim | 2 +- autoload/ale/assert.vim | 2 +- autoload/ale/definition.vim | 8 - autoload/ale/engine.vim | 130 +------ autoload/ale/fix.vim | 25 +- autoload/ale/linter.vim | 183 ++------- autoload/ale/lsp_linter.vim | 2 +- autoload/ale/test.vim | 4 +- doc/ale.txt | 22 +- plugin/ale.vim | 24 +- test/fix/test_ale_fix.vader | 108 ------ test/lsp/test_did_save_event.vader | 4 +- test/lsp/test_lsp_command_formatting.vader | 4 +- test/lsp/test_lsp_custom_request.vader | 1 - test/test_command_chain.vader | 73 ---- test/test_engine_invocation.vader | 108 ------ test/test_go_to_definition.vader | 2 +- test/test_linter_defintion_processing.vader | 387 +++----------------- test/test_temporary_file_management.vader | 2 +- 20 files changed, 125 insertions(+), 968 deletions(-) delete mode 100644 test/test_command_chain.vader delete mode 100644 test/test_engine_invocation.vader diff --git a/ale_linters/ocaml/ols.vim b/ale_linters/ocaml/ols.vim index d8208c52..ec71bdb4 100644 --- a/ale_linters/ocaml/ols.vim +++ b/ale_linters/ocaml/ols.vim @@ -9,6 +9,6 @@ call ale#linter#Define('ocaml', { \ 'lsp': 'stdio', \ 'executable': function('ale#handlers#ols#GetExecutable'), \ 'command': function('ale#handlers#ols#GetCommand'), -\ 'language_callback': 'ale#handlers#ols#GetLanguage', +\ 'language': function('ale#handlers#ols#GetLanguage'), \ 'project_root': function('ale#handlers#ols#GetProjectRoot'), \}) diff --git a/ale_linters/reason/ols.vim b/ale_linters/reason/ols.vim index 66137e1b..9fbd9b4f 100644 --- a/ale_linters/reason/ols.vim +++ b/ale_linters/reason/ols.vim @@ -9,6 +9,6 @@ call ale#linter#Define('reason', { \ 'lsp': 'stdio', \ 'executable': function('ale#handlers#ols#GetExecutable'), \ 'command': function('ale#handlers#ols#GetCommand'), -\ 'language_callback': 'ale#handlers#ols#GetLanguage', +\ 'language': function('ale#handlers#ols#GetLanguage'), \ 'project_root': function('ale#handlers#ols#GetProjectRoot'), \}) diff --git a/autoload/ale/assert.vim b/autoload/ale/assert.vim index 291edcee..934fcaa8 100644 --- a/autoload/ale/assert.vim +++ b/autoload/ale/assert.vim @@ -130,7 +130,7 @@ endfunction function! ale#assert#LSPLanguage(expected_language) abort let l:buffer = bufnr('') let l:linter = s:GetLinter() - let l:language = ale#util#GetFunction(l:linter.language_callback)(l:buffer) + let l:language = ale#linter#GetLanguage(l:buffer, l:linter) AssertEqual a:expected_language, l:language endfunction diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim index ffcd9d10..0c1fb7cf 100644 --- a/autoload/ale/definition.vim +++ b/autoload/ale/definition.vim @@ -135,10 +135,6 @@ function! s:GoToLSPDefinition(linter, options, capability) abort endfunction function! ale#definition#GoTo(options) abort - if !get(g:, 'ale_ignore_2_7_warnings') && has_key(a:options, 'deprecated_command') - execute 'echom '':' . a:options.deprecated_command . ' is deprecated. Use `let g:ale_ignore_2_7_warnings = 1` to disable this message.''' - endif - for l:linter in ale#linter#Get(&filetype) if !empty(l:linter.lsp) call s:GoToLSPDefinition(l:linter, a:options, 'definition') @@ -147,10 +143,6 @@ function! ale#definition#GoTo(options) abort endfunction function! ale#definition#GoToType(options) abort - if !get(g:, 'ale_ignore_2_7_warnings') && has_key(a:options, 'deprecated_command') - execute 'echom '':' . a:options.deprecated_command . ' is deprecated. Use `let g:ale_ignore_2_7_warnings = 1` to disable this message.''' - endif - for l:linter in ale#linter#Get(&filetype) if !empty(l:linter.lsp) " TODO: handle typeDefinition for tsserver if supported by the diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 491d3c2e..cfc1e5d7 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -104,42 +104,6 @@ function! ale#engine#IsCheckingBuffer(buffer) abort \ || !empty(get(l:info, 'active_other_sources_list', [])) endfunction -" Register a temporary file to be managed with the ALE engine for -" a current job run. -function! ale#engine#ManageFile(buffer, filename) abort - if !get(g:, 'ale_ignore_2_4_warnings') - execute 'echom ''ale#engine#ManageFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' - endif - - call ale#command#ManageFile(a:buffer, a:filename) -endfunction - -" Same as the above, but manage an entire directory. -function! ale#engine#ManageDirectory(buffer, directory) abort - if !get(g:, 'ale_ignore_2_4_warnings') - execute 'echom ''ale#engine#ManageDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' - endif - - call ale#command#ManageDirectory(a:buffer, a:directory) -endfunction - -function! ale#engine#CreateFile(buffer) abort - if !get(g:, 'ale_ignore_2_4_warnings') - execute 'echom ''ale#engine#CreateFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' - endif - - return ale#command#CreateFile(a:buffer) -endfunction - -" Create a new temporary directory and manage it in one go. -function! ale#engine#CreateDirectory(buffer) abort - if !get(g:, 'ale_ignore_2_4_warnings') - execute 'echom ''ale#engine#CreateDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' - endif - - return ale#command#CreateDirectory(a:buffer) -endfunction - function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort let l:info = get(g:ale_buffer_info, a:buffer, {}) @@ -192,7 +156,6 @@ function! s:HandleExit(job_info, buffer, output, data) abort let l:linter = a:job_info.linter let l:executable = a:job_info.executable - let l:next_chain_index = a:job_info.next_chain_index " Remove this job from the list. call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name) @@ -207,20 +170,6 @@ function! s:HandleExit(job_info, buffer, output, data) abort call remove(a:output, -1) endif - if l:next_chain_index < len(get(l:linter, 'command_chain', [])) - let [l:command, l:options] = ale#engine#ProcessChain( - \ a:buffer, - \ l:executable, - \ l:linter, - \ l:next_chain_index, - \ a:output, - \) - - call s:RunJob(l:command, l:options) - - return - endif - try let l:loclist = ale#util#GetFunction(l:linter.callback)(a:buffer, a:output) " Handle the function being unknown, or being deleted. @@ -454,20 +403,18 @@ function! s:RunJob(command, options) abort let l:buffer = a:options.buffer let l:linter = a:options.linter let l:output_stream = a:options.output_stream - let l:next_chain_index = a:options.next_chain_index let l:read_buffer = a:options.read_buffer let l:info = g:ale_buffer_info[l:buffer] let l:Callback = function('s:HandleExit', [{ \ 'linter': l:linter, \ 'executable': l:executable, - \ 'next_chain_index': l:next_chain_index, \}]) let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { \ 'output_stream': l:output_stream, \ 'executable': l:executable, \ 'read_buffer': l:read_buffer, - \ 'log_output': l:next_chain_index >= len(get(l:linter, 'command_chain', [])), + \ 'log_output': 1, \}) " Only proceed if the job is being run. @@ -482,68 +429,6 @@ function! s:RunJob(command, options) abort return 1 endfunction -" Determine which commands to run for a link in a command chain, or -" just a regular command. -function! ale#engine#ProcessChain(buffer, executable, linter, chain_index, input) abort - let l:output_stream = get(a:linter, 'output_stream', 'stdout') - let l:read_buffer = a:linter.read_buffer - let l:chain_index = a:chain_index - let l:input = a:input - - while l:chain_index < len(a:linter.command_chain) - " Run a chain of commands, one asynchronous command after the other, - " so that many programs can be run in a sequence. - let l:chain_item = a:linter.command_chain[l:chain_index] - - if l:chain_index == 0 - " The first callback in the chain takes only a buffer number. - let l:command = ale#util#GetFunction(l:chain_item.callback)( - \ a:buffer - \) - else - " The second callback in the chain takes some input too. - let l:command = ale#util#GetFunction(l:chain_item.callback)( - \ a:buffer, - \ l:input - \) - endif - - " If we have a command to run, execute that. - if !empty(l:command) - " The chain item can override the output_stream option. - if has_key(l:chain_item, 'output_stream') - let l:output_stream = l:chain_item.output_stream - endif - - " The chain item can override the read_buffer option. - if has_key(l:chain_item, 'read_buffer') - let l:read_buffer = l:chain_item.read_buffer - elseif l:chain_index != len(a:linter.command_chain) - 1 - " Don't read the buffer for commands besides the last one - " in the chain by default. - let l:read_buffer = 0 - endif - - break - endif - - " Command chain items can return an empty string to indicate that - " a command should be skipped, so we should try the next item - " with no input. - let l:input = [] - let l:chain_index += 1 - endwhile - - return [l:command, { - \ 'executable': a:executable, - \ 'buffer': a:buffer, - \ 'linter': a:linter, - \ 'output_stream': l:output_stream, - \ 'next_chain_index': l:chain_index + 1, - \ 'read_buffer': l:read_buffer, - \}] -endfunction - function! s:StopCurrentJobs(buffer, clear_lint_file_jobs) abort let l:info = get(g:ale_buffer_info, a:buffer, {}) call ale#command#StopJobs(a:buffer, 'linter') @@ -622,25 +507,12 @@ function! s:RunIfExecutable(buffer, linter, executable) abort let l:job_type = a:linter.lint_file ? 'file_linter' : 'linter' call setbufvar(a:buffer, 'ale_job_type', l:job_type) - if has_key(a:linter, 'command_chain') - let [l:command, l:options] = ale#engine#ProcessChain( - \ a:buffer, - \ a:executable, - \ a:linter, - \ 0, - \ [] - \) - - return s:RunJob(l:command, l:options) - endif - let l:command = ale#linter#GetCommand(a:buffer, a:linter) let l:options = { \ 'executable': a:executable, \ 'buffer': a:buffer, \ 'linter': a:linter, \ 'output_stream': get(a:linter, 'output_stream', 'stdout'), - \ 'next_chain_index': 1, \ 'read_buffer': a:linter.read_buffer, \} diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index 69817b36..b2a39444 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -90,7 +90,6 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort let l:output = a:job_output endif - let l:ChainCallback = get(a:job_info, 'chain_with', v:null) let l:ProcessWith = get(a:job_info, 'process_with', v:null) " Post-process the output with a function if we have one. @@ -102,27 +101,18 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort " otherwise skip this job and use the input from before. " " We'll use the input from before for chained commands. - if l:ChainCallback is v:null && !empty(split(join(l:output))) + if !empty(split(join(l:output))) let l:input = l:output else let l:input = a:job_info.input endif - if l:ChainCallback isnot v:null && !get(g:, 'ale_ignore_2_4_warnings') - execute 'echom ''chain_with is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' - endif - - let l:next_index = l:ChainCallback is v:null - \ ? a:job_info.callback_index + 1 - \ : a:job_info.callback_index - call s:RunFixer({ \ 'buffer': a:buffer, \ 'input': l:input, \ 'output': l:output, \ 'callback_list': a:job_info.callback_list, - \ 'callback_index': l:next_index, - \ 'chain_callback': l:ChainCallback, + \ 'callback_index': a:job_info.callback_index + 1, \}) endfunction @@ -152,17 +142,14 @@ function! s:RunJob(result, options) abort endif let l:command = get(a:result, 'command', '') - let l:ChainWith = get(a:result, 'chain_with', v:null) if empty(l:command) - " If the command is empty, skip to the next item, or call the - " chain_with function. + " If the command is empty, skip to the next item. call s:RunFixer({ \ 'buffer': l:buffer, \ 'input': l:input, - \ 'callback_index': a:options.callback_index + (l:ChainWith is v:null), + \ 'callback_index': a:options.callback_index, \ 'callback_list': a:options.callback_list, - \ 'chain_callback': l:ChainWith, \ 'output': [], \}) @@ -170,8 +157,7 @@ function! s:RunJob(result, options) abort endif let l:read_temporary_file = get(a:result, 'read_temporary_file', 0) - " Default to piping the buffer for the last fixer in the chain. - let l:read_buffer = get(a:result, 'read_buffer', l:ChainWith is v:null) + let l:read_buffer = get(a:result, 'read_buffer', 1) let l:output_stream = get(a:result, 'output_stream', 'stdout') if l:read_temporary_file @@ -180,7 +166,6 @@ function! s:RunJob(result, options) abort let l:Callback = function('s:HandleExit', [{ \ 'input': l:input, - \ 'chain_with': l:ChainWith, \ 'callback_index': a:options.callback_index, \ 'callback_list': a:options.callback_list, \ 'process_with': get(a:result, 'process_with', v:null), diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index 0e935149..fecfeed6 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -77,10 +77,6 @@ function! s:IsBoolean(value) abort return type(a:value) is v:t_number && (a:value == 0 || a:value == 1) endfunction -function! s:LanguageGetter(buffer) dict abort - return l:self.language -endfunction - function! ale#linter#PreProcess(filetype, linter) abort if type(a:linter) isnot v:t_dict throw 'The linter object must be a Dictionary' @@ -114,14 +110,7 @@ function! ale#linter#PreProcess(filetype, linter) abort if !l:needs_executable if has_key(a:linter, 'executable') - \|| has_key(a:linter, 'executable_callback') - throw '`executable` and `executable_callback` cannot be used when lsp == ''socket''' - endif - elseif has_key(a:linter, 'executable_callback') - let l:obj.executable_callback = a:linter.executable_callback - - if !s:IsCallback(l:obj.executable_callback) - throw '`executable_callback` must be a callback if defined' + throw '`executable` cannot be used when lsp == ''socket''' endif elseif has_key(a:linter, 'executable') let l:obj.executable = a:linter.executable @@ -131,54 +120,12 @@ function! ale#linter#PreProcess(filetype, linter) abort throw '`executable` must be a String or Function if defined' endif else - throw 'Either `executable` or `executable_callback` must be defined' + throw '`executable` must be defined' endif if !l:needs_command if has_key(a:linter, 'command') - \|| has_key(a:linter, 'command_callback') - \|| has_key(a:linter, 'command_chain') - throw '`command` and `command_callback` and `command_chain` cannot be used when lsp == ''socket''' - endif - elseif has_key(a:linter, 'command_chain') - let l:obj.command_chain = a:linter.command_chain - - if type(l:obj.command_chain) isnot v:t_list - throw '`command_chain` must be a List' - endif - - if empty(l:obj.command_chain) - throw '`command_chain` must contain at least one item' - endif - - let l:link_index = 0 - - for l:link in l:obj.command_chain - let l:err_prefix = 'The `command_chain` item ' . l:link_index . ' ' - - if !s:IsCallback(get(l:link, 'callback')) - throw l:err_prefix . 'must define a `callback` function' - endif - - if has_key(l:link, 'output_stream') - if type(l:link.output_stream) isnot v:t_string - \|| index(['stdout', 'stderr', 'both'], l:link.output_stream) < 0 - throw l:err_prefix . '`output_stream` flag must be ' - \ . "'stdout', 'stderr', or 'both'" - endif - endif - - if has_key(l:link, 'read_buffer') && !s:IsBoolean(l:link.read_buffer) - throw l:err_prefix . 'value for `read_buffer` must be `0` or `1`' - endif - - let l:link_index += 1 - endfor - elseif has_key(a:linter, 'command_callback') - let l:obj.command_callback = a:linter.command_callback - - if !s:IsCallback(l:obj.command_callback) - throw '`command_callback` must be a callback if defined' + throw '`command` cannot be used when lsp == ''socket''' endif elseif has_key(a:linter, 'command') let l:obj.command = a:linter.command @@ -188,22 +135,12 @@ function! ale#linter#PreProcess(filetype, linter) abort throw '`command` must be a String or Function if defined' endif else - throw 'Either `command`, `executable_callback`, `command_chain` ' - \ . 'must be defined' - endif - - if ( - \ has_key(a:linter, 'command') - \ + has_key(a:linter, 'command_chain') - \ + has_key(a:linter, 'command_callback') - \) > 1 - throw 'Only one of `command`, `command_callback`, or `command_chain` ' - \ . 'should be set' + throw '`command` must be defined' endif if !l:needs_address - if has_key(a:linter, 'address') || has_key(a:linter, 'address_callback') - throw '`address` or `address_callback` cannot be used when lsp != ''socket''' + if has_key(a:linter, 'address') + throw '`address` cannot be used when lsp != ''socket''' endif elseif has_key(a:linter, 'address') if type(a:linter.address) isnot v:t_string @@ -212,41 +149,17 @@ function! ale#linter#PreProcess(filetype, linter) abort endif let l:obj.address = a:linter.address - elseif has_key(a:linter, 'address_callback') - let l:obj.address_callback = a:linter.address_callback - - if !s:IsCallback(l:obj.address_callback) - throw '`address_callback` must be a callback if defined' - endif else - throw '`address` or `address_callback` must be defined for getting the LSP address' + throw '`address` must be defined for getting the LSP address' endif if l:needs_lsp_details - if has_key(a:linter, 'language_callback') - if has_key(a:linter, 'language') - throw 'Only one of `language` or `language_callback` ' - \ . 'should be set' - endif + " Default to using the filetype as the language. + let l:obj.language = get(a:linter, 'language', a:filetype) - let l:obj.language_callback = get(a:linter, 'language_callback') - - if !s:IsCallback(l:obj.language_callback) - throw '`language_callback` must be a callback for LSP linters' - endif - else - " Default to using the filetype as the language. - let l:Language = get(a:linter, 'language', a:filetype) - - if type(l:Language) is v:t_string - " Make 'language_callback' return the 'language' value. - let l:obj.language = l:Language - let l:obj.language_callback = function('s:LanguageGetter') - elseif type(l:Language) is v:t_func - let l:obj.language_callback = l:Language - else - throw '`language` must be a String or Funcref' - endif + if type(l:obj.language) isnot v:t_string + \&& type(l:obj.language) isnot v:t_func + throw '`language` must be a String or Funcref if defined' endif if has_key(a:linter, 'project_root') @@ -254,16 +167,10 @@ function! ale#linter#PreProcess(filetype, linter) abort if type(l:obj.project_root) isnot v:t_string \&& type(l:obj.project_root) isnot v:t_func - throw '`project_root` must be a String or Function if defined' - endif - elseif has_key(a:linter, 'project_root_callback') - let l:obj.project_root_callback = a:linter.project_root_callback - - if !s:IsCallback(l:obj.project_root_callback) - throw '`project_root_callback` must be a callback if defined' + throw '`project_root` must be a String or Function' endif else - throw '`project_root` or `project_root_callback` must be defined for LSP linters' + throw '`project_root` must be defined for LSP linters' endif if has_key(a:linter, 'completion_filter') @@ -274,37 +181,16 @@ function! ale#linter#PreProcess(filetype, linter) abort endif endif - if has_key(a:linter, 'initialization_options_callback') - if has_key(a:linter, 'initialization_options') - throw 'Only one of `initialization_options` or ' - \ . '`initialization_options_callback` should be set' - endif - - let l:obj.initialization_options_callback = a:linter.initialization_options_callback - - if !s:IsCallback(l:obj.initialization_options_callback) - throw '`initialization_options_callback` must be a callback if defined' - endif - elseif has_key(a:linter, 'initialization_options') + if has_key(a:linter, 'initialization_options') let l:obj.initialization_options = a:linter.initialization_options if type(l:obj.initialization_options) isnot v:t_dict \&& type(l:obj.initialization_options) isnot v:t_func - throw '`initialization_options` must be a String or Function if defined' + throw '`initialization_options` must be a Dictionary or Function if defined' endif endif - if has_key(a:linter, 'lsp_config_callback') - if has_key(a:linter, 'lsp_config') - throw 'Only one of `lsp_config` or `lsp_config_callback` should be set' - endif - - let l:obj.lsp_config_callback = a:linter.lsp_config_callback - - if !s:IsCallback(l:obj.lsp_config_callback) - throw '`lsp_config_callback` must be a callback if defined' - endif - elseif has_key(a:linter, 'lsp_config') + if has_key(a:linter, 'lsp_config') if type(a:linter.lsp_config) isnot v:t_dict \&& type(a:linter.lsp_config) isnot v:t_func throw '`lsp_config` must be a Dictionary or Function if defined' @@ -347,14 +233,6 @@ function! ale#linter#PreProcess(filetype, linter) abort throw '`aliases` must be a List of String values' endif - for l:key in filter(keys(a:linter), 'v:val[-9:] is# ''_callback'' || v:val is# ''command_chain''') - if !get(g:, 'ale_ignore_2_4_warnings') - execute 'echom l:key . '' is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' - endif - - break - endfor - return l:obj endfunction @@ -522,9 +400,7 @@ endfunction " Given a buffer and linter, get the executable String for the linter. function! ale#linter#GetExecutable(buffer, linter) abort - let l:Executable = has_key(a:linter, 'executable_callback') - \ ? function(a:linter.executable_callback) - \ : a:linter.executable + let l:Executable = a:linter.executable return type(l:Executable) is v:t_func \ ? l:Executable(a:buffer) @@ -532,24 +408,21 @@ function! ale#linter#GetExecutable(buffer, linter) abort endfunction " Given a buffer and linter, get the command String for the linter. -" The command_chain key is not supported. function! ale#linter#GetCommand(buffer, linter) abort - let l:Command = has_key(a:linter, 'command_callback') - \ ? function(a:linter.command_callback) - \ : a:linter.command + let l:Command = a:linter.command - return type(l:Command) is v:t_func - \ ? l:Command(a:buffer) - \ : l:Command + return type(l:Command) is v:t_func ? l:Command(a:buffer) : l:Command endfunction " Given a buffer and linter, get the address for connecting to the server. function! ale#linter#GetAddress(buffer, linter) abort - let l:Address = has_key(a:linter, 'address_callback') - \ ? function(a:linter.address_callback) - \ : a:linter.address + let l:Address = a:linter.address - return type(l:Address) is v:t_func - \ ? l:Address(a:buffer) - \ : l:Address + return type(l:Address) is v:t_func ? l:Address(a:buffer) : l:Address +endfunction + +function! ale#linter#GetLanguage(buffer, linter) abort + let l:Language = a:linter.language + + return type(l:Language) is v:t_func ? l:Language(a:buffer) : l:Language endfunction diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index e4148ceb..f4a42bf4 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -227,7 +227,7 @@ function! ale#lsp_linter#OnInit(linter, details, Callback) abort let l:command = a:details.command let l:config = ale#lsp_linter#GetConfig(l:buffer, a:linter) - let l:language_id = ale#util#GetFunction(a:linter.language_callback)(l:buffer) + let l:language_id = ale#linter#GetLanguage(l:buffer, a:linter) call ale#lsp#UpdateConfig(l:conn_id, l:buffer, l:config) diff --git a/autoload/ale/test.vim b/autoload/ale/test.vim index 082d91ff..6fcbf35e 100644 --- a/autoload/ale/test.vim +++ b/autoload/ale/test.vim @@ -145,8 +145,8 @@ function! ale#test#WaitForJobs(deadline) abort " end, but before handlers are run. sleep 10ms - " We must check the buffer data again to see if new jobs started - " for command_chain linters. + " We must check the buffer data again to see if new jobs started for + " linters with chained commands. let l:has_new_jobs = 0 " Check again to see if any jobs are running. diff --git a/doc/ale.txt b/doc/ale.txt index 50c0b8a0..606fe72c 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -684,7 +684,9 @@ g:ale_completion_enabled *g:ale_completion_enabled* See |ale-completion| -g:ale_completion_tsserver_remove_warnings *g:ale_completion_tsserver_remove_warnings* + + *g:ale_completion_tsserver_remove_warnings* +g:ale_completion_tsserver_remove_warnings Type: Number Default: `0` @@ -693,6 +695,7 @@ g:ale_completion_tsserver_remove_warnings *g:ale_completion_tsserver_remove_warn including those that are a warning. Warnings can be excluded from completed items by setting it to `1`. + g:ale_completion_autoimport *g:ale_completion_autoimport* Type: Number @@ -2809,7 +2812,13 @@ ALEGoToDefinition `` *ALEGoToDefinition* command. Otherwise, Vim will refuse to leave the buffer you're jumping from unless you have saved your edits. - A plug mapping `(ale_go_to_definition)` is defined for this command. + The following Plug mappings are defined for this command, which correspond + to the following commands. + + `(ale_go_to_definition)` - `:ALEGoToDefinition` + `(ale_go_to_definition_in_tab)` - `:ALEGoToDefinition -tab` + `(ale_go_to_definition_in_split)` - `:ALEGoToDefinition -split` + `(ale_go_to_definition_in_vsplit)` - `:ALEGoToDefinition -vsplit` ALEGoToTypeDefinition *ALEGoToTypeDefinition* @@ -2831,8 +2840,13 @@ ALEGoToTypeDefinition *ALEGoToTypeDefinition* You can jump back to the position you were at before going to the definition of something with jump motions like CTRL-O. See |jump-motions|. - A plug mapping `(ale_go_to_type_definition)` is defined for this - command. + The following Plug mappings are defined for this command, which correspond + to the following commands. + + `(ale_go_to_type_definition)` - `:ALEGoToTypeDefinition` + `(ale_go_to_type_definition_in_tab)` - `:ALEGoToTypeDefinition -tab` + `(ale_go_to_type_definition_in_split)` - `:ALEGoToTypeDefinition -split` + `(ale_go_to_type_definition_in_vsplit)` - `:ALEGoToTypeDefinition -vsplit` ALEHover *ALEHover* diff --git a/plugin/ale.vim b/plugin/ale.vim index 65c5a77c..0651dd4b 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -207,19 +207,9 @@ command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype) " Go to definition for tsserver and LSP command! -bar -nargs=* ALEGoToDefinition :call ale#definition#GoToCommandHandler('', ) -" Deprecated commands we have to keep for now. -command! -bar ALEGoToDefinitionInTab :call ale#definition#GoTo({'open_in': 'tab', 'deprecated_command': 'ALEGoToDefinitionInTab'}) -command! -bar ALEGoToDefinitionInSplit :call ale#definition#GoTo({'open_in': 'split', 'deprecated_command': 'ALEGoToDefinitionInSplit'}) -command! -bar ALEGoToDefinitionInVSplit :call ale#definition#GoTo({'open_in': 'vsplit', 'deprecated_command': 'ALEGoToDefinitionInVSplit'}) - " Go to type definition for tsserver and LSP command! -bar -nargs=* ALEGoToTypeDefinition :call ale#definition#GoToCommandHandler('type', ) -" Deprecated commands we have to keep for now. -command! -bar ALEGoToTypeDefinitionInTab :call ale#definition#GoToType({'open_in': 'tab', 'deprecated_command': 'ALEGoToTypeDefinitionInTab'}) -command! -bar ALEGoToTypeDefinitionInSplit :call ale#definition#GoToType({'open_in': 'split', 'deprecated_command': 'ALEGoToTypeDefinitionInSplit'}) -command! -bar ALEGoToTypeDefinitionInVSplit :call ale#definition#GoToType({'open_in': 'vsplit', 'deprecated_command': 'ALEGoToTypeDefinitionInVSplit'}) - " Repeat a previous selection in the preview window command! -bar ALERepeatSelection :call ale#preview#RepeatSelection() @@ -270,7 +260,13 @@ nnoremap (ale_lint) :ALELint nnoremap (ale_detail) :ALEDetail nnoremap (ale_fix) :ALEFix nnoremap (ale_go_to_definition) :ALEGoToDefinition +nnoremap (ale_go_to_definition_in_tab) :ALEGoToDefinition -tab +nnoremap (ale_go_to_definition_in_split) :ALEGoToDefinition -split +nnoremap (ale_go_to_definition_in_vsplit) :ALEGoToDefinition -vsplit nnoremap (ale_go_to_type_definition) :ALEGoToTypeDefinition +nnoremap (ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinition -tab +nnoremap (ale_go_to_type_definition_in_split) :ALEGoToTypeDefinition -split +nnoremap (ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionIn -vsplit nnoremap (ale_find_references) :ALEFindReferences nnoremap (ale_hover) :ALEHover nnoremap (ale_documentation) :ALEDocumentation @@ -278,14 +274,6 @@ inoremap (ale_complete) :ALEComplete nnoremap (ale_rename) :ALERename nnoremap (ale_repeat_selection) :ALERepeatSelection -" Deprecated mappings -nnoremap (ale_go_to_definition_in_tab) :ALEGoToDefinitionInTab -nnoremap (ale_go_to_definition_in_split) :ALEGoToDefinitionInSplit -nnoremap (ale_go_to_definition_in_vsplit) :ALEGoToDefinitionInVSplit -nnoremap (ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinitionInTab -nnoremap (ale_go_to_type_definition_in_split) :ALEGoToTypeDefinitionInSplit -nnoremap (ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionInVSplit - " Set up autocmd groups now. call ale#events#Init() diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader index 6081f4e2..53079d16 100644 --- a/test/fix/test_ale_fix.vader +++ b/test/fix/test_ale_fix.vader @@ -84,56 +84,6 @@ Before: return [{'lnum': 1, 'col': 1, 'text': 'xxx'}] endfunction - function! FirstChainCallback(buffer) - return {'command': 'echo echoline', 'chain_with': 'SecondChainCallback'} - endfunction - - function! FirstChainCallbackSkipped(buffer) - let l:ChainWith = 'SecondChainCallback' - - " Test with lambdas where support is available. - if has('lambda') - let l:ChainWith = {buffer, output -> SecondChainCallback(buffer, output)} - endif - - return {'command': '', 'chain_with': l:ChainWith} - endfunction - - function! FirstChainCallbackSecondSkipped(buffer) - return {'command': 'echo skipit', 'chain_with': 'SecondChainCallback'} - endfunction - - function! SecondChainCallback(buffer, output) - let l:previous_line = empty(a:output) - \ ? 'emptydefault' - \ : join(split(a:output[0])) - - if l:previous_line is# 'skipit' - return {'command': '', 'chain_with': 'ThirdChainCallback'} - endif - - return { - \ 'command': 'echo ' . l:previous_line, - \ 'chain_with': 'ThirdChainCallback', - \} - endfunction - - function! ThirdChainCallback(buffer, output, input) - let l:previous_line = empty(a:output) - \ ? 'thirddefault' - \ : join(split(a:output[0])) - - return a:input + [l:previous_line] - endfunction - - function! ChainWhereLastIsSkipped(buffer) - return {'command': 'echo echoline', 'chain_with': 'ChainEndSkipped'} - endfunction - - function! ChainEndSkipped(buffer, output) - return {'command': ''} - endfunction - " echo will output a single blank line, and we should ingore it. function! IgnoredEmptyOutput(buffer, output) return {'command': has('win32') ? 'echo(' : 'echo'} @@ -208,13 +158,6 @@ After: delfunction RemoveLastLine delfunction RemoveLastLineOneArg delfunction TestCallback - delfunction FirstChainCallback - delfunction FirstChainCallbackSkipped - delfunction FirstChainCallbackSecondSkipped - delfunction SecondChainCallback - delfunction ThirdChainCallback - delfunction ChainWhereLastIsSkipped - delfunction ChainEndSkipped delfunction SetUpLinters delfunction GetLastMessage delfunction IgnoredEmptyOutput @@ -816,57 +759,6 @@ Execute(ALE should tolerate valid fixers with minuses in the name): ALEFix call ale#test#FlushJobs() -Execute(Test fixing with chained callbacks): - let g:ale_fixers.testft = ['FirstChainCallback'] - ALEFix - call ale#test#FlushJobs() - - " The buffer shouldn't be piped in for earlier commands in the chain. - AssertEqual - \ [ - \ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')), - \ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')), - \ ], - \ map(ale#history#Get(bufnr(''))[-2:-1], 'string(v:val.command)') - -Expect(The echoed line should be added): - a - b - c - echoline - -Execute(Test fixing with chained callback where the first command is skipped): - let g:ale_fixers.testft = ['FirstChainCallbackSkipped'] - ALEFix - call ale#test#FlushJobs() - -Expect(The default line should be added): - a - b - c - emptydefault - -Execute(Test fixing with chained callback where the second command is skipped): - let g:ale_fixers.testft = ['FirstChainCallbackSecondSkipped'] - ALEFix - call ale#test#FlushJobs() - -Expect(The default line should be added): - a - b - c - thirddefault - -Execute(Test fixing with chained callback where the final callback is skipped): - let g:ale_fixers.testft = ['ChainWhereLastIsSkipped'] - ALEFix - call ale#test#FlushJobs() - -Expect(The lines should be the same): - a - b - c - Execute(Empty output should be ignored): let g:ale_fixers.testft = ['IgnoredEmptyOutput'] ALEFix diff --git a/test/lsp/test_did_save_event.vader b/test/lsp/test_did_save_event.vader index bdea6d98..1d811363 100644 --- a/test/lsp/test_did_save_event.vader +++ b/test/lsp/test_did_save_event.vader @@ -33,8 +33,8 @@ Before: \ 'lsp': 'stdio', \ 'command': 'cat - > /dev/null', \ 'executable': has('win32') ? 'cmd' : 'echo', - \ 'language_callback': 'LanguageCallback', - \ 'project_root_callback': 'ProjectRootCallback', + \ 'language': function('LanguageCallback'), + \ 'project_root': function('ProjectRootCallback'), \ }) let g:ale_linters = {'foobar': ['dummy_linter']} diff --git a/test/lsp/test_lsp_command_formatting.vader b/test/lsp/test_lsp_command_formatting.vader index 2c1e8788..e99e1dad 100644 --- a/test/lsp/test_lsp_command_formatting.vader +++ b/test/lsp/test_lsp_command_formatting.vader @@ -24,8 +24,8 @@ Execute(Command formatting should be applied correctly for LSP linters): \ bufnr(''), \ { \ 'name': 'linter', - \ 'language_callback': {-> 'x'}, - \ 'project_root_callback': {-> '/foo/bar'}, + \ 'language': {-> 'x'}, + \ 'project_root': {-> '/foo/bar'}, \ 'lsp': 'stdio', \ 'executable': has('win32') ? 'cmd': 'true', \ 'command': '%e --foo', diff --git a/test/lsp/test_lsp_custom_request.vader b/test/lsp/test_lsp_custom_request.vader index 04f044af..c8767e59 100644 --- a/test/lsp/test_lsp_custom_request.vader +++ b/test/lsp/test_lsp_custom_request.vader @@ -25,7 +25,6 @@ Before: \ 'name': g:linter_name, \ 'project_root': {b -> g:project_root}, \ 'aliases': [], - \ 'language_callback': {b -> 'cpp'}, \ 'read_buffer': 1, \ 'command': '%e' \ }] diff --git a/test/test_command_chain.vader b/test/test_command_chain.vader deleted file mode 100644 index 329ebc97..00000000 --- a/test/test_command_chain.vader +++ /dev/null @@ -1,73 +0,0 @@ -Before: - Save &shell, g:ale_run_synchronously - let g:ale_run_synchronously = 1 - unlet! g:ale_run_synchronously_callbacks - - if !has('win32') - set shell=/bin/sh - endif - - let g:linter_output = [] - let g:first_echo_called = 0 - let g:second_echo_called = 0 - let g:final_callback_called = 0 - - function! CollectResults(buffer, output) - let g:final_callback_called = 1 - let g:linter_output = map(copy(a:output), 'join(split(v:val))') - return [] - endfunction - function! RunFirstEcho(buffer) - let g:first_echo_called = 1 - - return 'echo foo' - endfunction - function! RunSecondEcho(buffer, output) - let g:second_echo_called = 1 - - return 'echo bar' - endfunction - - call ale#linter#Define('foobar', { - \ 'name': 'testlinter', - \ 'callback': 'CollectResults', - \ 'executable': has('win32') ? 'cmd' : 'echo', - \ 'command_chain': [ - \ { - \ 'callback': 'RunFirstEcho', - \ 'output_stream': 'stdout', - \ 'read_buffer': 0, - \ }, - \ { - \ 'callback': 'RunSecondEcho', - \ 'output_stream': 'stdout', - \ 'read_buffer': 0, - \ }, - \ ], - \}) - -After: - Restore - unlet! g:ale_run_synchronously_callbacks - unlet! g:first_echo_called - unlet! g:second_echo_called - unlet! g:final_callback_called - unlet! g:linter_output - let g:ale_buffer_info = {} - call ale#linter#Reset() - delfunction CollectResults - delfunction RunFirstEcho - delfunction RunSecondEcho - -Given foobar (Some imaginary filetype): - anything - -Execute(Check the results of running the chain): - AssertEqual 'foobar', &filetype - call ale#Queue(0) - call ale#test#FlushJobs() - - Assert g:first_echo_called, 'The first chain item was not called' - Assert g:second_echo_called, 'The second chain item was not called' - Assert g:final_callback_called, 'The final callback was not called' - AssertEqual ['bar'], g:linter_output diff --git a/test/test_engine_invocation.vader b/test/test_engine_invocation.vader deleted file mode 100644 index af713953..00000000 --- a/test/test_engine_invocation.vader +++ /dev/null @@ -1,108 +0,0 @@ -Before: - function! CollectResults(buffer, output) - return [] - endfunction - - function! FirstChainFunction(buffer) - return 'first' - endfunction - - function! SecondChainFunction(buffer, output) - " We'll skip this command - return '' - endfunction - - function! ThirdChainFunction(buffer, output) - return 'third' - endfunction - - function! FourthChainFunction(buffer, output) - return 'fourth' - endfunction - - let g:linter = { - \ 'name': 'testlinter', - \ 'callback': 'CollectResults', - \ 'executable': 'echo', - \ 'command_chain': [ - \ {'callback': 'FirstChainFunction'}, - \ {'callback': 'SecondChainFunction'}, - \ {'callback': 'ThirdChainFunction'}, - \ {'callback': 'FourthChainFunction'}, - \ ], - \ 'read_buffer': 1, - \} - - function! ProcessIndex(chain_index) - let [l:command, l:options] = ale#engine#ProcessChain(347, '', g:linter, a:chain_index, []) - let l:options.command = l:command - - return l:options - endfunction - -After: - delfunction CollectResults - delfunction FirstChainFunction - delfunction SecondChainFunction - delfunction ThirdChainFunction - delfunction ProcessIndex - unlet! g:linter - unlet! g:result - -Execute(Engine invocation should return the command for the first item correctly): - let g:result = ProcessIndex(0) - - AssertEqual 'first', g:result.command - AssertEqual 1, g:result.next_chain_index - -Execute(Engine invocation should return the command for the second item correctly): - let g:result = ProcessIndex(1) - - AssertEqual 'third', g:result.command - AssertEqual 3, g:result.next_chain_index - -Execute(Engine invocation should return the command for the fourth item correctly): - let g:result = ProcessIndex(3) - - AssertEqual 'fourth', g:result.command - AssertEqual 4, g:result.next_chain_index - -Execute(Engine invocation should allow read_buffer to be enabled for a command in the middle of a chain): - let g:linter.command_chain[2].read_buffer = 1 - - let g:result = ProcessIndex(2) - - AssertEqual g:result.command, 'third' - AssertEqual g:result.read_buffer, 1 - -Execute(Engine invocation should allow read_buffer to be disabled for the end of a chain): - let g:linter.command_chain[3].read_buffer = 0 - - let g:result = ProcessIndex(3) - - AssertEqual g:result.command, 'fourth' - AssertEqual g:result.read_buffer, 0 - -Execute(Engine invocation should not use read_buffer from earlier items in a chain): - let g:linter.command_chain[1].read_buffer = 1 - - let g:result = ProcessIndex(1) - - AssertEqual g:result.command, 'third' - AssertEqual g:result.read_buffer, 0 - -Execute(Engine invocation should allow the output_stream setting to be changed in the middle of a chain): - let g:linter.command_chain[2].output_stream = 'both' - - let g:result = ProcessIndex(2) - - AssertEqual g:result.command, 'third' - AssertEqual g:result.output_stream, 'both' - -Execute(Engine invocation should not use output_stream from earlier items in a chain): - let g:linter.command_chain[1].output_stream = 'both' - - let g:result = ProcessIndex(1) - - AssertEqual g:result.command, 'third' - AssertEqual g:result.output_stream, 'stdout' diff --git a/test/test_go_to_definition.vader b/test/test_go_to_definition.vader index a517bd54..f2f34280 100644 --- a/test/test_go_to_definition.vader +++ b/test/test_go_to_definition.vader @@ -514,7 +514,7 @@ Execute(LSP tab type definition requests should be sent): let b:ale_linters = ['pyls'] call setpos('.', [bufnr(''), 1, 5, 0]) - ALEGoToTypeDefinitionInTab + ALEGoToTypeDefinition -tab " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) diff --git a/test/test_linter_defintion_processing.vader b/test/test_linter_defintion_processing.vader index cd32ebc8..2c85299b 100644 --- a/test/test_linter_defintion_processing.vader +++ b/test/test_linter_defintion_processing.vader @@ -39,13 +39,13 @@ Execute (PreProcess should throw when then callback is not a function): \}) AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception -Execute (PreProcess should throw when there is no executable or executable_callback): +Execute (PreProcess should throw when there is no executable): AssertThrows call ale#linter#PreProcess('testft', { \ 'name': 'foo', \ 'callback': 'SomeFunction', \ 'command': 'echo', \}) - AssertEqual 'Either `executable` or `executable_callback` must be defined', g:vader_exception + AssertEqual '`executable` must be defined', g:vader_exception Execute (PreProcess should throw when executable is not a string): AssertThrows call ale#linter#PreProcess('testft', { @@ -56,15 +56,6 @@ Execute (PreProcess should throw when executable is not a string): \}) AssertEqual '`executable` must be a String or Function if defined', g:vader_exception -Execute (PreProcess should throw when executable_callback is not a callback): - AssertThrows call ale#linter#PreProcess('testft', { - \ 'name': 'foo', - \ 'callback': 'SomeFunction', - \ 'executable_callback': 123, - \ 'command': 'echo', - \}) - AssertEqual '`executable_callback` must be a callback if defined', g:vader_exception - Execute (PreProcess should allow executable to be a callback): call ale#linter#PreProcess('testft', { \ 'name': 'foo', @@ -79,7 +70,7 @@ Execute (PreProcess should throw when there is no command): \ 'callback': 'SomeFunction', \ 'executable': 'echo', \}) - AssertEqual 'Either `command`, `executable_callback`, `command_chain` must be defined', g:vader_exception + AssertEqual '`command` must be defined', g:vader_exception Execute (PreProcess should throw when command is not a string): AssertThrows call ale#linter#PreProcess('testft', { @@ -98,15 +89,6 @@ Execute (PreProcess should allow command to be a callback): \ 'command': function('type'), \}) -Execute (PreProcess should throw when command_callback is not a callback): - AssertThrows call ale#linter#PreProcess('testft', { - \ 'name': 'foo', - \ 'callback': 'SomeFunction', - \ 'executable': 'echo', - \ 'command_callback': 123, - \}) - AssertEqual '`command_callback` must be a callback if defined', g:vader_exception - Execute (PreProcess should when the output stream isn't a valid string): AssertThrows call ale#linter#PreProcess('testft', { \ 'name': 'foo', @@ -152,117 +134,12 @@ Execute (PreProcess should accept a 'both' output_stream): \ 'output_stream': 'both', \}) -Execute(PreProcess should complain if the command_chain is not a List): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': 'x', - \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual '`command_chain` must be a List', g:vader_exception - -Execute(PreProcess should complain if the command_chain is empty): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': [], - \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual '`command_chain` must contain at least one item', g:vader_exception - -Execute(PreProcess should complain if the command_chain has no callback): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': [{}], - \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'The `command_chain` item 0 must define a `callback` function', g:vader_exception - -Execute(PreProcess should complain if the command_chain callback is not a function): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': [{'callback': 2}], - \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'The `command_chain` item 0 must define a `callback` function', g:vader_exception - -Execute(PreProcess should accept a chain with one callback): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': [{'callback': 'foo'}], - \} - call ale#linter#PreProcess('testft', g:linter) - -Execute(PreProcess should complain about invalid output_stream values in the chain): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': [{'callback': 'foo', 'output_stream': ''}], - \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual "The `command_chain` item 0 `output_stream` flag must be 'stdout', 'stderr', or 'both'", g:vader_exception - -Execute(PreProcess should complain about valid output_stream values in the chain): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': [{'callback': 'foo', 'output_stream': 'stdout'}], - \} - call ale#linter#PreProcess('testft', g:linter) - let g:linter.command_chain[0].output_stream = 'stderr' - call ale#linter#PreProcess('testft', g:linter) - let g:linter.command_chain[0].output_stream = 'both' - call ale#linter#PreProcess('testft', g:linter) - -Execute(PreProcess should complain about invalid chain items at higher indices): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command_chain': [{'callback': 'foo'}, {'callback': 123}], - \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'The `command_chain` item 1 must define a `callback` function', g:vader_exception - -Execute(PreProcess should complain when conflicting command options are used): - let g:linter = { - \ 'name': 'x', - \ 'callback': 'x', - \ 'executable': 'x', - \ 'command': 'foo', - \ 'command_chain': [{'callback': 'foo'}], - \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception - - unlet g:linter.command - let g:linter.command_callback = 'foo' - - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception - - let g:linter.command = 'foo' - unlet g:linter.command_chain - - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception - Execute(PreProcess should process the read_buffer option correctly): let g:linter = { \ 'name': 'x', \ 'callback': 'x', \ 'executable': 'x', - \ 'command_chain': [{'callback': 'foo'}, {'callback': 'bar'}], + \ 'command': 'x', \ 'read_buffer': '0', \} @@ -277,25 +154,6 @@ Execute(PreProcess should process the read_buffer option correctly): call ale#linter#PreProcess('testft', g:linter) - unlet g:linter.read_buffer - let g:linter.command_chain[0].read_buffer = '0' - - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'The `command_chain` item 0 value for `read_buffer` must be `0` or `1`', g:vader_exception - - let g:linter.command_chain[0].read_buffer = 0 - - call ale#linter#PreProcess('testft', g:linter) - - let g:linter.command_chain[1].read_buffer = '0' - - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'The `command_chain` item 1 value for `read_buffer` must be `0` or `1`', g:vader_exception - - let g:linter.command_chain[1].read_buffer = 1 - - call ale#linter#PreProcess('testft', g:linter) - Execute(PreProcess should set a default value for read_buffer): let g:linter = { \ 'name': 'x', @@ -394,151 +252,96 @@ Execute(PreProcess should accept tsserver LSP configuration): \ 'executable': 'x', \ 'command': 'x', \ 'lsp': 'tsserver', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'language': 'x', + \ 'project_root': 'x', \} AssertEqual 'tsserver', ale#linter#PreProcess('testft', g:linter).lsp - call remove(g:linter, 'executable') - let g:linter.executable_callback = 'X' - - call ale#linter#PreProcess('testft', g:linter) - - call remove(g:linter, 'command') - let g:linter.command_callback = 'X' - - call ale#linter#PreProcess('testft', g:linter) - Execute(PreProcess should accept stdio LSP configuration): let g:linter = { \ 'name': 'x', \ 'executable': 'x', \ 'command': 'x', \ 'lsp': 'stdio', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'language': 'x', + \ 'project_root': 'x', \} AssertEqual 'stdio', ale#linter#PreProcess('testft', g:linter).lsp - call remove(g:linter, 'executable') - let g:linter.executable_callback = 'X' - - call ale#linter#PreProcess('testft', g:linter) - - call remove(g:linter, 'command') - let g:linter.command_callback = 'X' - - call ale#linter#PreProcess('testft', g:linter) - Execute(PreProcess should accept LSP server configurations): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'address': 'X', + \ 'language': 'foobar', + \ 'project_root': 'x', \} AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp -Execute(PreProcess should accept let you specify the language as just a string): +Execute(PreProcess should accept let you specify the `language` as a Function): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': 'foobar', - \ 'project_root_callback': 'x', + \ 'address': 'X', + \ 'language': {-> 'foobar'}, + \ 'project_root': 'x', \} - AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language_callback(0) - -Execute(PreProcess should complain about using language and language_callback together): - let g:linter = { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': 'x', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', - \} - - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'Only one of `language` or `language_callback` should be set', g:vader_exception + AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language(bufnr('')) Execute(PreProcess should complain about invalid language values): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 0, - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \} AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual '`language` must be a String or Funcref', g:vader_exception + AssertEqual '`language` must be a String or Funcref if defined', g:vader_exception Execute(PreProcess should use the filetype as the language string by default): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'project_root_callback': 'x', + \ 'address': 'X', + \ 'project_root': 'x', \} - AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language_callback(0) + AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language -Execute(PreProcess should allow language to be set to a callback): - let g:linter = { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': {-> 'foo'}, - \ 'project_root_callback': 'x', - \} - - AssertEqual 'foo', ale#linter#PreProcess('testft', g:linter).language_callback(0) - -Execute(PreProcess should require an address_callback for LSP socket configurations): +Execute(PreProcess should require an `address` for LSP socket configurations): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', \} AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual '`address` or `address_callback` must be defined for getting the LSP address', g:vader_exception + AssertEqual '`address` must be defined for getting the LSP address', g:vader_exception -Execute(PreProcess should complain about address_callback for non-LSP linters): +Execute(PreProcess should complain about `address` for non-LSP linters): let g:linter = { \ 'name': 'x', \ 'callback': 'SomeFunction', \ 'executable': 'echo', \ 'command': 'echo', - \ 'address_callback': 'X', + \ 'address': 'X', \} AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual '`address` or `address_callback` cannot be used when lsp != ''socket''', g:vader_exception + AssertEqual '`address` cannot be used when lsp != ''socket''', g:vader_exception -Execute(PreProcess accept valid address_callback values): - let g:linter = ale#linter#PreProcess('testft', { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address_callback': {-> 'foo:123'}, - \ 'language': 'x', - \ 'project_root_callback': 'x', - \}) - - AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) - -Execute(PreProcess accept address as a String): +Execute(PreProcess accept `address` as a String): let g:linter = ale#linter#PreProcess('testft', { \ 'name': 'x', \ 'lsp': 'socket', \ 'address': 'foo:123', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \}) AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) @@ -549,7 +352,7 @@ Execute(PreProcess accept address as a Function): \ 'lsp': 'socket', \ 'address': {-> 'foo:123'}, \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \}) AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) @@ -560,11 +363,11 @@ Execute(PreProcess should complain about invalid address values): \ 'lsp': 'socket', \ 'address': 0, \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \}) AssertEqual '`address` must be a String or Function if defined', g:vader_exception -Execute(PreProcess should accept allow the project root be set as a String): +Execute(PreProcess should allow the `project_root` to be set as a String): let g:linter = ale#linter#PreProcess('testft', { \ 'name': 'x', \ 'lsp': 'socket', @@ -575,7 +378,7 @@ Execute(PreProcess should accept allow the project root be set as a String): AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter) -Execute(PreProcess should accept allow the project root be set as a Function): +Execute(PreProcess should `project_root` be set as a Function): let g:linter = ale#linter#PreProcess('testft', { \ 'name': 'x', \ 'lsp': 'socket', @@ -586,7 +389,7 @@ Execute(PreProcess should accept allow the project root be set as a Function): AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter) -Execute(PreProcess should complain when the project_root valid is invalid): +Execute(PreProcess should complain when `project_root` is invalid): AssertThrows call ale#linter#PreProcess('testft', { \ 'name': 'x', \ 'lsp': 'socket', @@ -594,154 +397,74 @@ Execute(PreProcess should complain when the project_root valid is invalid): \ 'language': 'x', \ 'project_root': 0, \}) - AssertEqual '`project_root` must be a String or Function if defined', g:vader_exception + AssertEqual '`project_root` must be a String or Function', g:vader_exception -Execute(PreProcess should accept project_root_callback as a String): - call ale#linter#PreProcess('testft', { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address': 'foo:123', - \ 'language': 'x', - \ 'project_root_callback': 'Foobar', - \}) - -Execute(PreProcess should accept project_root_callback as a Function): - let g:linter = ale#linter#PreProcess('testft', { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address': 'foo:123', - \ 'language': 'x', - \ 'project_root_callback': {-> '/foo/bar'}, - \}) - - AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter) - -Execute(PreProcess should complain when the project_root_callback valid is invalid): - AssertThrows call ale#linter#PreProcess('testft', { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address': 'foo:123', - \ 'language': 'x', - \ 'project_root_callback': 0, - \}) - AssertEqual '`project_root_callback` must be a callback if defined', g:vader_exception - -Execute(PreProcess should complain about using initialization_options and initialization_options_callback together): - let g:linter = { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': 'x', - \ 'project_root_callback': 'x', - \ 'initialization_options': 'x', - \ 'initialization_options_callback': 'x', - \} - - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'Only one of `initialization_options` or `initialization_options_callback` should be set', g:vader_exception - -Execute(PreProcess should throw when initialization_options_callback is not a callback): +Execute(PreProcess should throw when `initialization_options` is not a Dictionary or callback): AssertThrows call ale#linter#PreProcess('testft', { \ 'name': 'foo', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', - \ 'initialization_options_callback': {}, - \}) - AssertEqual '`initialization_options_callback` must be a callback if defined', g:vader_exception - -Execute(PreProcess should throw when initialization_options is not a Dictionary or callback): - AssertThrows call ale#linter#PreProcess('testft', { - \ 'name': 'foo', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'initialization_options': 0, \}) - AssertEqual '`initialization_options` must be a String or Function if defined', g:vader_exception + AssertEqual '`initialization_options` must be a Dictionary or Function if defined', g:vader_exception -Execute(PreProcess should accept initialization_options as a Dictionary): +Execute(PreProcess should accept `initialization_options` as a Dictionary): let g:linter = ale#linter#PreProcess('testft', { \ 'name': 'foo', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'initialization_options': {'foo': v:true}, \}) AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter) -Execute(PreProcess should accept initialization_options as a Funcref): +Execute(PreProcess should accept `initialization_options` as a Function): let g:linter = ale#linter#PreProcess('testft', { \ 'name': 'foo', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'initialization_options': {-> {'foo': v:true}}, \}) AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter) -Execute(PreProcess should complain about using lsp_config and lsp_config_callback together): +Execute(PreProcess should accept `lsp_config` as a Dictionary): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', - \ 'lsp_config': 'x', - \ 'lsp_config_callback': 'x', - \} - - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'Only one of `lsp_config` or `lsp_config_callback` should be set', g:vader_exception - -Execute(PreProcess should throw when lsp_config_callback is not a callback): - AssertThrows call ale#linter#PreProcess('testft', { - \ 'name': 'foo', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': 'x', - \ 'project_root_callback': 'x', - \ 'lsp_config_callback': {}, - \}) - AssertEqual '`lsp_config_callback` must be a callback if defined', g:vader_exception - -Execute(PreProcess should accept LSP configuration options via lsp_config): - let g:linter = { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'lsp_config': {'foo': 'bar'}, \} AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter) -Execute(PreProcess should accept LSP configuration options via lsp_config as a function): +Execute(PreProcess should accept `lsp_config` as a Function): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', \ 'lsp_config': {-> {'foo': 'bar'}}, \} AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter) -Execute(PreProcess should throw when lsp_config is not a Dictionary or Function): +Execute(PreProcess should throw when `lsp_config` is not a Dictionary or Function): AssertThrows call ale#linter#PreProcess('testft', { \ 'name': 'foo', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'lsp_config': 'x', \}) AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception diff --git a/test/test_temporary_file_management.vader b/test/test_temporary_file_management.vader index 9fff1ace..bb735886 100644 --- a/test/test_temporary_file_management.vader +++ b/test/test_temporary_file_management.vader @@ -40,7 +40,7 @@ Before: \ 'name': 'testlinter', \ 'executable': has('win32') ? 'cmd' : 'echo', \ 'callback': 'TestCallback', - \ 'command_callback': 'TestCommandCallback', + \ 'command': function('TestCommandCallback'), \}) call ale#command#ClearData() From 794224aafa6968dd635a96b66ddf218dfdea38d8 Mon Sep 17 00:00:00 2001 From: w0rp Date: Wed, 19 Aug 2020 00:47:39 +0100 Subject: [PATCH 15/20] #3056 Add tests for parsed C/C++ -std flag handling --- .../test_c_clang_command_callbacks.vader | 17 +++++++++++++++ .../test_c_gcc_command_callbacks.vader | 21 +++++++++++++++++-- .../test_cpp_clang_command_callbacks.vader | 18 ++++++++++++++++ .../test_cpp_gcc_command_callbacks.vader | 18 ++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/test/command_callback/test_c_clang_command_callbacks.vader b/test/command_callback/test_c_clang_command_callbacks.vader index b8c02e4d..01be18e0 100644 --- a/test/command_callback/test_c_clang_command_callbacks.vader +++ b/test/command_callback/test_c_clang_command_callbacks.vader @@ -2,14 +2,25 @@ Before: Save g:ale_c_parse_makefile let g:ale_c_parse_makefile = 0 + let g:get_cflags_return_value = '' + + runtime autoload/ale/c.vim + + function! ale#c#GetCFlags(buffer, output) abort + return g:get_cflags_return_value + endfunction + call ale#assert#SetUpLinterTest('c', 'clang') let b:command_tail = ' -S -x c -fsyntax-only -iquote' \ . ' ' . ale#Escape(getcwd()) \ . ' -std=c11 -Wall -' After: + unlet! g:get_cflags_return_value unlet! b:command_tail + runtime autoload/ale/c.vim + call ale#assert#TearDownLinterTest() Execute(The executable should be configurable): @@ -18,3 +29,9 @@ Execute(The executable should be configurable): let b:ale_c_clang_executable = 'foobar' AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail] + +Execute(The -std flag should be replaced by parsed C flags): + let b:command_tail = substitute(b:command_tail, 'c11', 'c99 ', '') + let g:get_cflags_return_value = '-std=c99' + + AssertLinter 'clang', ale#Escape('clang') . b:command_tail diff --git a/test/command_callback/test_c_gcc_command_callbacks.vader b/test/command_callback/test_c_gcc_command_callbacks.vader index 2dbb8b7c..ee5d9030 100644 --- a/test/command_callback/test_c_gcc_command_callbacks.vader +++ b/test/command_callback/test_c_gcc_command_callbacks.vader @@ -1,5 +1,13 @@ Before: Save g:ale_c_parse_makefile + let g:get_cflags_return_value = '' + + runtime autoload/ale/c.vim + + function! ale#c#GetCFlags(buffer, output) abort + return g:get_cflags_return_value + endfunction + let g:ale_c_parse_makefile = 0 call ale#assert#SetUpLinterTest('c', 'gcc') @@ -10,13 +18,22 @@ Before: \ . ' -std=c11 -Wall -' After: - call ale#assert#TearDownLinterTest() - + unlet! g:get_cflags_return_value unlet! b:command_tail + runtime autoload/ale/c.vim + + call ale#assert#TearDownLinterTest() + Execute(The executable should be configurable): AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail] let b:ale_c_gcc_executable = 'foobar' AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail] + +Execute(The -std flag should be replaced by parsed C flags): + let b:command_tail = substitute(b:command_tail, 'c11', 'c99 ', '') + let g:get_cflags_return_value = '-std=c99' + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail diff --git a/test/command_callback/test_cpp_clang_command_callbacks.vader b/test/command_callback/test_cpp_clang_command_callbacks.vader index e96fd8e7..7d5fe989 100644 --- a/test/command_callback/test_cpp_clang_command_callbacks.vader +++ b/test/command_callback/test_cpp_clang_command_callbacks.vader @@ -2,13 +2,25 @@ Before: Save g:ale_c_parse_makefile let g:ale_c_parse_makefile = 0 + let g:get_cflags_return_value = '' + + runtime autoload/ale/c.vim + + function! ale#c#GetCFlags(buffer, output) abort + return g:get_cflags_return_value + endfunction + call ale#assert#SetUpLinterTest('cpp', 'clang') let b:command_tail = ' -S -x c++ -fsyntax-only -iquote' \ . ' ' . ale#Escape(getcwd()) \ . ' -std=c++14 -Wall -' After: + unlet! g:get_cflags_return_value unlet! b:command_tail + + runtime autoload/ale/c.vim + call ale#assert#TearDownLinterTest() Execute(The executable should be configurable): @@ -17,3 +29,9 @@ Execute(The executable should be configurable): let b:ale_cpp_clang_executable = 'foobar' AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail + +Execute(The -std flag should be replaced by parsed C flags): + let b:command_tail = substitute(b:command_tail, 'c++14', 'c++11 ', '') + let g:get_cflags_return_value = '-std=c++11' + + AssertLinter 'clang++', ale#Escape('clang++') . b:command_tail diff --git a/test/command_callback/test_cpp_gcc_command_callbacks.vader b/test/command_callback/test_cpp_gcc_command_callbacks.vader index cfa4ecc0..9a64e6a4 100644 --- a/test/command_callback/test_cpp_gcc_command_callbacks.vader +++ b/test/command_callback/test_cpp_gcc_command_callbacks.vader @@ -2,6 +2,14 @@ Before: Save g:ale_c_parse_makefile let g:ale_c_parse_makefile = 0 + let g:get_cflags_return_value = '' + + runtime autoload/ale/c.vim + + function! ale#c#GetCFlags(buffer, output) abort + return g:get_cflags_return_value + endfunction + call ale#assert#SetUpLinterTest('cpp', 'gcc') let b:command_tail = ' -S -x c++' \ . ' -o ' . (has('win32') ? 'nul': '/dev/null') @@ -9,7 +17,11 @@ Before: \ . ' -std=c++14 -Wall -' After: + unlet! g:get_cflags_return_value unlet! b:command_tail + + runtime autoload/ale/c.vim + call ale#assert#TearDownLinterTest() Execute(The executable should be configurable): @@ -18,3 +30,9 @@ Execute(The executable should be configurable): let b:ale_cpp_gcc_executable = 'foobar' AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail + +Execute(The -std flag should be replaced by parsed C flags): + let b:command_tail = substitute(b:command_tail, 'c++14', 'c++11 ', '') + let g:get_cflags_return_value = '-std=c++11' + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail From 361027eac6b8a3e9e4e88d6ec7f13e17e909f641 Mon Sep 17 00:00:00 2001 From: w0rp Date: Wed, 19 Aug 2020 01:04:08 +0100 Subject: [PATCH 16/20] Fix #3200 - Do not use -fstack-usage from parsed flags --- autoload/ale/c.vim | 2 +- test/test_c_flag_parsing.vader | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index be54cff1..aefe1fea 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -159,7 +159,7 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0) \ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0 \ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0 - \ || (stridx(l:option, '-f') == 0 && stridx(l:option, '-fdump') != 0 && stridx(l:option, '-fdiagnostics') != 0 && stridx(l:option, '-fno-show-column') != 0) + \ || stridx(l:option, '-f') == 0 && l:option !~# '\v^-f(dump|diagnostics|no-show-column|stack-usage)' \ || stridx(l:option, '-O') == 0 \ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs' \ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0 diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index dff19aa3..5f52264e 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -364,7 +364,7 @@ Execute(CFlags we dont want to pass): \ ale#c#ParseCFlags( \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), \ 'gcc -Wl,option -Wa,option -Wp,option filename.c somelib.a ' - \ . '-fdump-file=name -fdiagnostics-arg -fno-show-column' + \ . '-fdump-file=name -fdiagnostics-arg -fno-show-column -fstack-usage' \ ) Execute(Expanding @file in CFlags): From de7b0567b11555005a9b2ec051327891bcb8f2b4 Mon Sep 17 00:00:00 2001 From: w0rp Date: Wed, 19 Aug 2020 01:10:33 +0100 Subject: [PATCH 17/20] Try to fix tests on Windows --- autoload/ale/c.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index aefe1fea..fee993ab 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -173,7 +173,7 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort endfunction function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort - if !g:ale_c_parse_makefile + if !get(g:, 'ale_c_parse_makefile', 0) return v:null endif From 90abb7e7efbb9d7cbd3bfcb2beceed08bb901ebe Mon Sep 17 00:00:00 2001 From: w0rp Date: Wed, 19 Aug 2020 01:22:43 +0100 Subject: [PATCH 18/20] Try to fix Windows tests again --- autoload/ale/c.vim | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index fee993ab..0ec724b3 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -8,6 +8,14 @@ let s:sep = has('win32') ? '\' : '/' " Set just so tests can override it. let g:__ale_c_project_filenames = ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt'] +function! s:CanParseMakefile(buffer) abort + " Something somewhere seems to delete this setting in tests, so ensure we + " always have a default value. + call ale#Set('c_parse_makefile', 0) + + return ale#Var(a:buffer, 'c_parse_makefile') +endfunction + function! ale#c#GetBuildDirectory(buffer) abort let l:build_dir = ale#Var(a:buffer, 'c_build_dir') @@ -173,7 +181,7 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort endfunction function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort - if !get(g:, 'ale_c_parse_makefile', 0) + if !s:CanParseMakefile(a:buffer) return v:null endif @@ -383,9 +391,7 @@ function! ale#c#GetCFlags(buffer, output) abort endif endif - if ale#Var(a:buffer, 'c_parse_makefile') - \&& !empty(a:output) - \&& !empty(l:cflags) + if s:CanParseMakefile(a:buffer) && !empty(a:output) && !empty(l:cflags) let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output) endif @@ -397,7 +403,7 @@ function! ale#c#GetCFlags(buffer, output) abort endfunction function! ale#c#GetMakeCommand(buffer) abort - if ale#Var(a:buffer, 'c_parse_makefile') + if s:CanParseMakefile(a:buffer) let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile') if !empty(l:makefile_path) From 4d42ebc160d7cccd19c37ffe2ccb97752794be37 Mon Sep 17 00:00:00 2001 From: awang Date: Wed, 19 Aug 2020 23:09:02 +0000 Subject: [PATCH 19/20] Keep -iframework if present in parsed C/C++ flags (#3057) * Keep -iframework if present in parsed C/C++ flags * Add test to make sure -iframework is parsed Co-authored-by: Alex Wang --- autoload/ale/c.vim | 1 + test/test_c_flag_parsing.vader | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index 0ec724b3..5cf4c690 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -132,6 +132,7 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort \ || stridx(l:option, '-iquote') == 0 \ || stridx(l:option, '-isystem') == 0 \ || stridx(l:option, '-idirafter') == 0 + \ || stridx(l:option, '-iframework') == 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/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index 5f52264e..e9830db8 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -340,6 +340,7 @@ Execute(CFlags we want to pass): \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incquote')) \ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incsystem')) \ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter')) + \ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incframework')) \ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2' \ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3' \ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir' @@ -349,7 +350,7 @@ Execute(CFlags we want to pass): \ ale#c#ParseCFlags( \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), \ 'gcc' - \ . ' -Iinc -I include -iquote incquote -isystem incsystem -idirafter incafter' + \ . ' -Iinc -I include -iquote incquote -isystem incsystem -idirafter incafter -iframework incframework' \ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2' \ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3' \ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir' From 2b785688ead505dcbc1007374d3dca9914aa247a Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 20 Aug 2020 01:46:29 +0100 Subject: [PATCH 20/20] #3299 Merge gcc and clang into a cc linter Users can easily be confused when they set some options for a C or C++ compiler, and another compiler is run with different options, which still reports errors. To remedy this, the existing `gcc` and `clang` linters have been replaced with a `cc` linter that will run either compiler. This is a breaking change for ALE v3.0.0. --- ale_linters/c/{gcc.vim => cc.vim} | 32 +++- ale_linters/c/clang.vim | 33 ---- ale_linters/cpp/cc.vim | 53 ++++++ ale_linters/cpp/clang.vim | 33 ---- ale_linters/cpp/gcc.vim | 38 ----- doc/ale-c.txt | 117 ++++++------- doc/ale-cpp.txt | 125 +++++++------- doc/ale-supported-languages-and-tools.txt | 8 +- doc/ale.txt | 12 +- ...ader => test_c_cc_command_callbacks.vader} | 24 ++- .../test_c_clang_command_callbacks.vader | 37 ----- .../test_c_import_paths.vader | 154 ++++-------------- .../test_cpp_clang_command_callbacks.vader | 37 ----- .../test_cpp_gcc_command_callbacks.vader | 25 ++- .../test_clangtidy_fixer_callback.vader | 24 ++- 15 files changed, 282 insertions(+), 470 deletions(-) rename ale_linters/c/{gcc.vim => cc.vim} (53%) delete mode 100644 ale_linters/c/clang.vim create mode 100644 ale_linters/cpp/cc.vim delete mode 100644 ale_linters/cpp/clang.vim delete mode 100644 ale_linters/cpp/gcc.vim rename test/command_callback/{test_c_gcc_command_callbacks.vader => test_c_cc_command_callbacks.vader} (62%) delete mode 100644 test/command_callback/test_c_clang_command_callbacks.vader delete mode 100644 test/command_callback/test_cpp_clang_command_callbacks.vader diff --git a/ale_linters/c/gcc.vim b/ale_linters/c/cc.vim similarity index 53% rename from ale_linters/c/gcc.vim rename to ale_linters/c/cc.vim index 252285a3..6d920ab0 100644 --- a/ale_linters/c/gcc.vim +++ b/ale_linters/c/cc.vim @@ -1,12 +1,27 @@ " Author: w0rp -" Description: gcc linter for c files +" Description: A C compiler linter for C files with gcc/clang, etc. -call ale#Set('c_gcc_executable', 'gcc') -call ale#Set('c_gcc_options', '-std=c11 -Wall') +call ale#Set('c_cc_executable', '') +call ale#Set('c_cc_options', '-std=c11 -Wall') -function! ale_linters#c#gcc#GetCommand(buffer, output) abort +function! ale_linters#c#cc#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'c_cc_executable') + + " Default to either clang or gcc. + if l:executable is# '' + if ale#engine#IsExecutable(a:buffer, 'clang') + let l:executable = 'clang' + else + let l:executable = 'gcc' + endif + endif + + return l:executable +endfunction + +function! ale_linters#c#cc#GetCommand(buffer, output) abort let l:cflags = ale#c#GetCFlags(a:buffer, a:output) - let l:ale_flags = ale#Var(a:buffer, 'c_gcc_options') + let l:ale_flags = ale#Var(a:buffer, 'c_cc_options') if l:cflags =~# '-std=' let l:ale_flags = substitute( @@ -29,9 +44,10 @@ function! ale_linters#c#gcc#GetCommand(buffer, output) abort endfunction call ale#linter#Define('c', { -\ 'name': 'gcc', +\ 'name': 'cc', +\ 'aliases': ['gcc', 'clang'], \ 'output_stream': 'stderr', -\ 'executable': {b -> ale#Var(b, 'c_gcc_executable')}, -\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#gcc#GetCommand'))}, +\ 'executable': function('ale_linters#c#cc#GetExecutable'), +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#cc#GetCommand'))}, \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \}) diff --git a/ale_linters/c/clang.vim b/ale_linters/c/clang.vim deleted file mode 100644 index 84c105de..00000000 --- a/ale_linters/c/clang.vim +++ /dev/null @@ -1,33 +0,0 @@ -" Author: Masahiro H https://github.com/mshr-h -" Description: clang linter for c files - -call ale#Set('c_clang_executable', 'clang') -call ale#Set('c_clang_options', '-std=c11 -Wall') - -function! ale_linters#c#clang#GetCommand(buffer, output) abort - let l:cflags = ale#c#GetCFlags(a:buffer, a:output) - let l:ale_flags = ale#Var(a:buffer, 'c_clang_options') - - if l:cflags =~# '-std=' - let l:ale_flags = substitute( - \ l:ale_flags, - \ '-std=\(c\|gnu\)[0-9]\{2\}', - \ '', - \ 'g') - endif - - " -iquote with the directory the file is in makes #include work for - " headers in the same directory. - return '%e -S -x c -fsyntax-only' - \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) - \ . ale#Pad(l:cflags) - \ . ale#Pad(l:ale_flags) . ' -' -endfunction - -call ale#linter#Define('c', { -\ 'name': 'clang', -\ 'output_stream': 'stderr', -\ 'executable': {b -> ale#Var(b, 'c_clang_executable')}, -\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clang#GetCommand'))}, -\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', -\}) diff --git a/ale_linters/cpp/cc.vim b/ale_linters/cpp/cc.vim new file mode 100644 index 00000000..eed3898f --- /dev/null +++ b/ale_linters/cpp/cc.vim @@ -0,0 +1,53 @@ +" Author: w0rp +" Description: A C++ compiler linter for C++ files with gcc/clang, etc. + +call ale#Set('cpp_cc_executable', '') +call ale#Set('cpp_cc_options', '-std=c++14 -Wall') + +function! ale_linters#cpp#cc#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'cpp_cc_executable') + + " Default to either clang++ or gcc. + if l:executable is# '' + if ale#engine#IsExecutable(a:buffer, 'clang++') + let l:executable = 'clang++' + else + let l:executable = 'gcc' + endif + endif + + return l:executable +endfunction + +function! ale_linters#cpp#cc#GetCommand(buffer, output) abort + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:ale_flags = ale#Var(a:buffer, 'cpp_cc_options') + + if l:cflags =~# '-std=' + let l:ale_flags = substitute( + \ l:ale_flags, + \ '-std=\(c\|gnu\)++[0-9]\{2\}', + \ '', + \ 'g') + endif + + " -iquote with the directory the file is in makes #include work for + " headers in the same directory. + " + " `-o /dev/null` or `-o null` is needed to catch all errors, + " -fsyntax-only doesn't catch everything. + return '%e -S -x c++' + \ . ' -o ' . g:ale#util#nul_file + \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ale#Pad(l:cflags) + \ . ale#Pad(l:ale_flags) . ' -' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'cc', +\ 'aliases': ['gcc', 'clang', 'g++', 'clang++'], +\ 'output_stream': 'stderr', +\ 'executable': function('ale_linters#cpp#cc#GetExecutable'), +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#cc#GetCommand'))}, +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/ale_linters/cpp/clang.vim b/ale_linters/cpp/clang.vim deleted file mode 100644 index d93638ec..00000000 --- a/ale_linters/cpp/clang.vim +++ /dev/null @@ -1,33 +0,0 @@ -" Author: Tomota Nakamura -" Description: clang linter for cpp files - -call ale#Set('cpp_clang_executable', 'clang++') -call ale#Set('cpp_clang_options', '-std=c++14 -Wall') - -function! ale_linters#cpp#clang#GetCommand(buffer, output) abort - let l:cflags = ale#c#GetCFlags(a:buffer, a:output) - let l:ale_flags = ale#Var(a:buffer, 'cpp_clang_options') - - if l:cflags =~# '-std=' - let l:ale_flags = substitute( - \ l:ale_flags, - \ '-std=\(c\|gnu\)++[0-9]\{2\}', - \ '', - \ 'g') - endif - - " -iquote with the directory the file is in makes #include work for - " headers in the same directory. - return '%e -S -x c++ -fsyntax-only' - \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) - \ . ale#Pad(l:cflags) - \ . ale#Pad(l:ale_flags) . ' -' -endfunction - -call ale#linter#Define('cpp', { -\ 'name': 'clang', -\ 'output_stream': 'stderr', -\ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')}, -\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clang#GetCommand'))}, -\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', -\}) diff --git a/ale_linters/cpp/gcc.vim b/ale_linters/cpp/gcc.vim deleted file mode 100644 index 89c2d358..00000000 --- a/ale_linters/cpp/gcc.vim +++ /dev/null @@ -1,38 +0,0 @@ -" Author: geam -" Description: gcc linter for cpp files -" -call ale#Set('cpp_gcc_executable', 'gcc') -call ale#Set('cpp_gcc_options', '-std=c++14 -Wall') - -function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort - let l:cflags = ale#c#GetCFlags(a:buffer, a:output) - let l:ale_flags = ale#Var(a:buffer, 'cpp_gcc_options') - - if l:cflags =~# '-std=' - let l:ale_flags = substitute( - \ l:ale_flags, - \ '-std=\(c\|gnu\)++[0-9]\{2\}', - \ '', - \ 'g') - endif - - " -iquote with the directory the file is in makes #include work for - " headers in the same directory. - " - " `-o /dev/null` or `-o null` is needed to catch all errors, - " -fsyntax-only doesn't catch everything. - return '%e -S -x c++' - \ . ' -o ' . g:ale#util#nul_file - \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) - \ . ale#Pad(l:cflags) - \ . ale#Pad(l:ale_flags) . ' -' -endfunction - -call ale#linter#Define('cpp', { -\ 'name': 'gcc', -\ 'aliases': ['g++'], -\ 'output_stream': 'stderr', -\ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')}, -\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#gcc#GetCommand'))}, -\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', -\}) diff --git a/doc/ale-c.txt b/doc/ale-c.txt index fc0d941a..fe28cf4a 100644 --- a/doc/ale-c.txt +++ b/doc/ale-c.txt @@ -1,6 +1,9 @@ =============================================================================== ALE C Integration *ale-c-options* +For basic checking of problems with C files, ALE offers the `cc` linter, which +runs either `clang`, or `gcc`. See |ale-c-cc|. + =============================================================================== Global Options @@ -11,12 +14,12 @@ g:ale_c_build_dir_names *g:ale_c_build_dir_names* Type: |List| Default: `['build', 'bin']` - A list of directory names to be used when searching upwards from cpp - files to discover compilation databases with. For directory named `'foo'`, - ALE will search for `'foo/compile_commands.json'` in all directories on and above - the directory containing the cpp file to find path to compilation database. - This feature is useful for the clang tools wrapped around LibTooling (namely - here, clang-tidy) + A list of directory names to be used when searching upwards from cpp files + to discover compilation databases with. For directory named `'foo'`, ALE + will search for `'foo/compile_commands.json'` in all directories on and + above the directory containing the cpp file to find path to compilation + database. This feature is useful for the clang tools wrapped around + LibTooling (namely here, clang-tidy) g:ale_c_build_dir *g:ale_c_build_dir* @@ -94,22 +97,58 @@ g:ale_c_astyle_project_options *g:ale_c_astyle_project_options* =============================================================================== -clang *ale-c-clang* +cc *ale-c-cc* + *ale-c-gcc* + *ale-c-clang* -g:ale_c_clang_executable *g:ale_c_clang_executable* - *b:ale_c_clang_executable* +g:ale_c_cc_executable *g:ale_c_cc_executable* + *b:ale_c_cc_executable* Type: |String| - Default: `'clang'` + Default: `''` - This variable can be changed to use a different executable for clang. + This variable can be changed to use a different executable for a C compiler. + + ALE will try to use `clang` if Clang is available, otherwise ALE will + default to checking C code with `gcc`. -g:ale_c_clang_options *g:ale_c_clang_options* - *b:ale_c_clang_options* +g:ale_c_cc_options *g:ale_c_cc_options* + *b:ale_c_cc_options* Type: |String| Default: `'-std=c11 -Wall'` - This variable can be changed to modify flags given to clang. + This variable can be change to modify flags given to the C compiler. + + +=============================================================================== +ccls *ale-c-ccls* + +g:ale_c_ccls_executable *g:ale_c_ccls_executable* + *b:ale_c_ccls_executable* + Type: |String| + Default: `'ccls'` + + This variable can be changed to use a different executable for ccls. + + +g:ale_c_ccls_init_options *g:ale_c_ccls_init_options* + *b:ale_c_ccls_init_options* + Type: |Dictionary| + Default: `{}` + + This variable can be changed to customize ccls initialization options. + Example: > + { + \ 'cacheDirectory': '/tmp/ccls', + \ 'cacheFormat': 'binary', + \ 'diagnostics': { + \ 'onOpen': 0, + \ 'opChange': 1000, + \ }, + \ } +< + Visit https://github.com/MaskRay/ccls/wiki/Initialization-options for all + available options and explanations. =============================================================================== @@ -294,25 +333,6 @@ g:ale_c_flawfinder_error_severity *g:ale_c_flawfinder_error_severity* error. This setting also applies to flawfinder for c++. -=============================================================================== -gcc *ale-c-gcc* - -g:ale_c_gcc_executable *g:ale_c_gcc_executable* - *b:ale_c_gcc_executable* - Type: |String| - Default: `'gcc'` - - This variable can be changed to use a different executable for gcc. - - -g:ale_c_gcc_options *g:ale_c_gcc_options* - *b:ale_c_gcc_options* - Type: |String| - Default: `'-std=c11 -Wall'` - - This variable can be change to modify flags given to gcc. - - =============================================================================== uncrustify *ale-c-uncrustify* @@ -332,36 +352,5 @@ g:ale_c_uncrustify_options *g:ale_c_uncrustify_options* This variable can be change to modify flags given to uncrustify. -=============================================================================== -ccls *ale-c-ccls* - -g:ale_c_ccls_executable *g:ale_c_ccls_executable* - *b:ale_c_ccls_executable* - Type: |String| - Default: `'ccls'` - - This variable can be changed to use a different executable for ccls. - - -g:ale_c_ccls_init_options *g:ale_c_ccls_init_options* - *b:ale_c_ccls_init_options* - Type: |Dictionary| - Default: `{}` - - This variable can be changed to customize ccls initialization options. - Example: > - { - \ 'cacheDirectory': '/tmp/ccls', - \ 'cacheFormat': 'binary', - \ 'diagnostics': { - \ 'onOpen': 0, - \ 'opChange': 1000, - \ }, - \ } -< - Visit https://github.com/MaskRay/ccls/wiki/Initialization-options for all - available options and explanations. - - =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-cpp.txt b/doc/ale-cpp.txt index fbe31370..651b4160 100644 --- a/doc/ale-cpp.txt +++ b/doc/ale-cpp.txt @@ -1,6 +1,9 @@ =============================================================================== ALE C++ Integration *ale-cpp-options* +For basic checking of problems with C++ files, ALE offers the `cc` linter, +which runs either `clang++`, or `gcc`. See |ale-cpp-cc|. + =============================================================================== Global Options @@ -38,41 +41,58 @@ g:ale_cpp_astyle_project_options *g:ale_cpp_astyle_project_options* =============================================================================== -clang *ale-cpp-clang* +cc *ale-cpp-cc* + *ale-cpp-gcc* + *ale-cpp-clang* -g:ale_cpp_clang_executable *g:ale_cpp_clang_executable* - *b:ale_cpp_clang_executable* +g:ale_cpp_cc_executable *g:ale_cpp_cc_executable* + *b:ale_cpp_cc_executable* Type: |String| - Default: `'clang++'` + Default: `''` - This variable can be changed to use a different executable for clang. + This variable can be changed to use a different executable for a C++ compiler. + + ALE will try to use `clang++` if Clang is available, otherwise ALE will + default to checking C++ code with `gcc`. -g:ale_cpp_clang_options *g:ale_cpp_clang_options* - *b:ale_cpp_clang_options* +g:ale_cpp_cc_options *g:ale_cpp_cc_options* + *b:ale_cpp_cc_options* Type: |String| Default: `'-std=c++14 -Wall'` - This variable can be changed to modify flags given to clang. + This variable can be change to modify flags given to the C++ compiler. =============================================================================== -clangd *ale-cpp-clangd* +ccls *ale-cpp-ccls* -g:ale_cpp_clangd_executable *g:ale_cpp_clangd_executable* - *b:ale_cpp_clangd_executable* +g:ale_cpp_ccls_executable *g:ale_cpp_ccls_executable* + *b:ale_cpp_ccls_executable* Type: |String| - Default: `'clangd'` + Default: `'ccls'` - This variable can be changed to use a different executable for clangd. + This variable can be changed to use a different executable for ccls. -g:ale_cpp_clangd_options *g:ale_cpp_clangd_options* - *b:ale_cpp_clangd_options* - Type: |String| - Default: `''` +g:ale_cpp_ccls_init_options *g:ale_cpp_ccls_init_options* + *b:ale_cpp_ccls_init_options* + Type: |Dictionary| + Default: `{}` - This variable can be changed to modify flags given to clangd. + This variable can be changed to customize ccls initialization options. + Example: > + { + \ 'cacheDirectory': '/tmp/ccls', + \ 'cacheFormat': 'binary', + \ 'diagnostics': { + \ 'onOpen': 0, + \ 'opChange': 1000, + \ }, + \ } +< + Visit https://github.com/MaskRay/ccls/wiki/Initialization-options for all + available options and explanations. =============================================================================== @@ -106,6 +126,25 @@ g:ale_cpp_clangcheck_options *g:ale_cpp_clangcheck_options* option. +=============================================================================== +clangd *ale-cpp-clangd* + +g:ale_cpp_clangd_executable *g:ale_cpp_clangd_executable* + *b:ale_cpp_clangd_executable* + Type: |String| + Default: `'clangd'` + + This variable can be changed to use a different executable for clangd. + + +g:ale_cpp_clangd_options *g:ale_cpp_clangd_options* + *b:ale_cpp_clangd_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clangd. + + =============================================================================== clang-format *ale-cpp-clangformat* @@ -295,61 +334,11 @@ g:ale_cpp_flawfinder_options *g:ale-cpp-flawfinder* This variable can be used to pass extra options into the flawfinder command. -=============================================================================== -gcc *ale-cpp-gcc* - -g:ale_cpp_gcc_executable *g:ale_cpp_gcc_executable* - *b:ale_cpp_gcc_executable* - Type: |String| - Default: `'gcc'` - - This variable can be changed to use a different executable for gcc. - - -g:ale_cpp_gcc_options *g:ale_cpp_gcc_options* - *b:ale_cpp_gcc_options* - Type: |String| - Default: `'-std=c++14 -Wall'` - - This variable can be changed to modify flags given to gcc. - - =============================================================================== uncrustify *ale-cpp-uncrustify* See |ale-c-uncrustify| for information about the available options. -=============================================================================== -ccls *ale-cpp-ccls* - -g:ale_cpp_ccls_executable *g:ale_cpp_ccls_executable* - *b:ale_cpp_ccls_executable* - Type: |String| - Default: `'ccls'` - - This variable can be changed to use a different executable for ccls. - - -g:ale_cpp_ccls_init_options *g:ale_cpp_ccls_init_options* - *b:ale_cpp_ccls_init_options* - Type: |Dictionary| - Default: `{}` - - This variable can be changed to customize ccls initialization options. - Example: > - { - \ 'cacheDirectory': '/tmp/ccls', - \ 'cacheFormat': 'binary', - \ 'diagnostics': { - \ 'onOpen': 0, - \ 'opChange': 1000, - \ }, - \ } -< - Visit https://github.com/MaskRay/ccls/wiki/Initialization-options for all - available options and explanations. - - =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 632dc468..677267d8 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -48,7 +48,7 @@ Notes: * C * `astyle` * `ccls` - * `clang` + * `clang` (`cc`) * `clangd` * `clang-format` * `clangtidy`!! @@ -56,7 +56,7 @@ Notes: * `cpplint`!! * `cquery` * `flawfinder` - * `gcc` + * `gcc` (`cc`) * `uncrustify` * C# * `csc`!! @@ -66,7 +66,7 @@ Notes: * C++ (filetype cpp) * `astyle` * `ccls` - * `clang` + * `clang` (`cc`) * `clangcheck`!! * `clangd` * `clang-format` @@ -76,7 +76,7 @@ Notes: * `cpplint`!! * `cquery` * `flawfinder` - * `gcc` + * `gcc` (`cc`) * `uncrustify` * Chef * `cookstyle` diff --git a/doc/ale.txt b/doc/ale.txt index 606fe72c..81271105 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2322,16 +2322,15 @@ documented in additional help files. bibclean..............................|ale-bib-bibclean| c.......................................|ale-c-options| astyle................................|ale-c-astyle| - clang.................................|ale-c-clang| + cc....................................|ale-c-cc| + ccls..................................|ale-c-ccls| clangd................................|ale-c-clangd| clang-format..........................|ale-c-clangformat| clangtidy.............................|ale-c-clangtidy| cppcheck..............................|ale-c-cppcheck| cquery................................|ale-c-cquery| flawfinder............................|ale-c-flawfinder| - gcc...................................|ale-c-gcc| uncrustify............................|ale-c-uncrustify| - ccls..................................|ale-c-ccls| chef....................................|ale-chef-options| cookstyle.............................|ale-chef-cookstyle| foodcritic............................|ale-chef-foodcritic| @@ -2345,9 +2344,10 @@ documented in additional help files. cmake-format..........................|ale-cmake-cmakeformat| cpp.....................................|ale-cpp-options| astyle................................|ale-cpp-astyle| - clang.................................|ale-cpp-clang| - clangd................................|ale-cpp-clangd| + cc....................................|ale-cpp-cc| + ccls..................................|ale-cpp-ccls| clangcheck............................|ale-cpp-clangcheck| + clangd................................|ale-cpp-clangd| clang-format..........................|ale-cpp-clangformat| clangtidy.............................|ale-cpp-clangtidy| clazy.................................|ale-cpp-clazy| @@ -2355,9 +2355,7 @@ documented in additional help files. cpplint...............................|ale-cpp-cpplint| cquery................................|ale-cpp-cquery| flawfinder............................|ale-cpp-flawfinder| - gcc...................................|ale-cpp-gcc| uncrustify............................|ale-cpp-uncrustify| - ccls..................................|ale-cpp-ccls| c#......................................|ale-cs-options| csc...................................|ale-cs-csc| mcs...................................|ale-cs-mcs| diff --git a/test/command_callback/test_c_gcc_command_callbacks.vader b/test/command_callback/test_c_cc_command_callbacks.vader similarity index 62% rename from test/command_callback/test_c_gcc_command_callbacks.vader rename to test/command_callback/test_c_cc_command_callbacks.vader index ee5d9030..9d71d941 100644 --- a/test/command_callback/test_c_gcc_command_callbacks.vader +++ b/test/command_callback/test_c_cc_command_callbacks.vader @@ -1,16 +1,25 @@ Before: Save g:ale_c_parse_makefile + Save g:ale_history_enabled + + let g:ale_c_parse_makefile = 0 + let g:ale_history_enabled = 0 + let g:get_cflags_return_value = '' + let g:executable_map = {} runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim + + function! ale#engine#IsExecutable(buffer, executable) abort + return has_key(g:executable_map, a:executable) + endfunction function! ale#c#GetCFlags(buffer, output) abort return g:get_cflags_return_value endfunction - let g:ale_c_parse_makefile = 0 - - call ale#assert#SetUpLinterTest('c', 'gcc') + call ale#assert#SetUpLinterTest('c', 'cc') let b:command_tail = ' -S -x c' \ . ' -o ' . (has('win32') ? 'nul': '/dev/null') @@ -19,16 +28,23 @@ Before: After: unlet! g:get_cflags_return_value + unlet! g:executable_map unlet! b:command_tail runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim call ale#assert#TearDownLinterTest() +Execute(clang should be used instead of gcc, if available): + let g:executable_map = {'clang': 1} + + AssertLinter 'clang', [ale#Escape('clang') . b:command_tail] + Execute(The executable should be configurable): AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail] - let b:ale_c_gcc_executable = 'foobar' + let b:ale_c_cc_executable = 'foobar' AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail] diff --git a/test/command_callback/test_c_clang_command_callbacks.vader b/test/command_callback/test_c_clang_command_callbacks.vader deleted file mode 100644 index 01be18e0..00000000 --- a/test/command_callback/test_c_clang_command_callbacks.vader +++ /dev/null @@ -1,37 +0,0 @@ -Before: - Save g:ale_c_parse_makefile - let g:ale_c_parse_makefile = 0 - - let g:get_cflags_return_value = '' - - runtime autoload/ale/c.vim - - function! ale#c#GetCFlags(buffer, output) abort - return g:get_cflags_return_value - endfunction - - call ale#assert#SetUpLinterTest('c', 'clang') - let b:command_tail = ' -S -x c -fsyntax-only -iquote' - \ . ' ' . ale#Escape(getcwd()) - \ . ' -std=c11 -Wall -' - -After: - unlet! g:get_cflags_return_value - unlet! b:command_tail - - runtime autoload/ale/c.vim - - call ale#assert#TearDownLinterTest() - -Execute(The executable should be configurable): - AssertLinter 'clang', [ale#Escape('clang') . b:command_tail] - - let b:ale_c_clang_executable = 'foobar' - - AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail] - -Execute(The -std flag should be replaced by parsed C flags): - let b:command_tail = substitute(b:command_tail, 'c11', 'c99 ', '') - let g:get_cflags_return_value = '-std=c99' - - AssertLinter 'clang', ale#Escape('clang') . b:command_tail diff --git a/test/command_callback/test_c_import_paths.vader b/test/command_callback/test_c_import_paths.vader index e6102998..8384a659 100644 --- a/test/command_callback/test_c_import_paths.vader +++ b/test/command_callback/test_c_import_paths.vader @@ -7,6 +7,7 @@ Before: Save g:__ale_c_project_filenames let g:original_project_filenames = g:__ale_c_project_filenames + let g:executable_map = {} " Remove the .git/HEAD dir for C import paths for these tests. " The tests run inside of a git repo. @@ -18,17 +19,26 @@ Before: let g:ale_c_parse_compile_commands = 0 let g:ale_c_parse_makefile = 0 + runtime autoload/ale/engine.vim + + function! ale#engine#IsExecutable(buffer, executable) abort + return has_key(g:executable_map, a:executable) + endfunction + After: Restore unlet! g:original_project_filenames + unlet! g:executable_map + + runtime autoload/ale/engine.vim call ale#assert#TearDownLinterTest() -Execute(The C GCC handler should include 'include' directories for projects with a Makefile): - call ale#assert#SetUpLinterTest('c', 'gcc') +Execute(The C cc linter should include 'include' directories for projects with a Makefile): + call ale#assert#SetUpLinterTest('c', 'cc') call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.c') - let g:ale_c_gcc_options = '' + let g:ale_c_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -37,10 +47,10 @@ Execute(The C GCC handler should include 'include' directories for projects with \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include')) \ . ' -' -Execute(The C GCC handler should include 'include' directories for projects with a configure file): - call ale#assert#SetUpLinterTest('c', 'gcc') +Execute(The C cc linter should include 'include' directories for projects with a configure file): + call ale#assert#SetUpLinterTest('c', 'cc') call ale#test#SetFilename('../test_c_projects/configure_project/subdir/file.c') - let g:ale_c_gcc_options = '' + let g:ale_c_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -49,10 +59,10 @@ Execute(The C GCC handler should include 'include' directories for projects with \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include')) \ . ' -' -Execute(The C GCC handler should include root directories for projects with .h files in them): - call ale#assert#SetUpLinterTest('c', 'gcc') +Execute(The C cc linter should include root directories for projects with .h files in them): + call ale#assert#SetUpLinterTest('c', 'cc') call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.c') - let g:ale_c_gcc_options = '' + let g:ale_c_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -61,10 +71,10 @@ Execute(The C GCC handler should include root directories for projects with .h f \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project')) \ . ' -' -Execute(The C GCC handler should include root directories for projects with .hpp files in them): - call ale#assert#SetUpLinterTest('c', 'gcc') +Execute(The C cc linter should include root directories for projects with .hpp files in them): + call ale#assert#SetUpLinterTest('c', 'cc') call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.c') - let g:ale_c_gcc_options = '' + let g:ale_c_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -73,54 +83,6 @@ Execute(The C GCC handler should include root directories for projects with .hpp \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project')) \ . ' -' -Execute(The C Clang handler should include 'include' directories for projects with a Makefile): - call ale#assert#SetUpLinterTest('c', 'clang') - call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.c') - let g:ale_c_clang_options = '' - - AssertLinter 'clang', - \ ale#Escape('clang') - \ . ' -S -x c -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include')) - \ . ' -' - -Execute(The C Clang handler should include 'include' directories for projects with a configure file): - call ale#assert#SetUpLinterTest('c', 'clang') - call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.c') - let g:ale_c_clang_options = '' - - AssertLinter 'clang', - \ ale#Escape('clang') - \ . ' -S -x c -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project')) - \ . ' -' - -Execute(The C Clang handler should include root directories for projects with .h files in them): - call ale#assert#SetUpLinterTest('c', 'clang') - call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.c') - let g:ale_c_clang_options = '' - - AssertLinter 'clang', - \ ale#Escape('clang') - \ . ' -S -x c -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project')) - \ . ' -' - -Execute(The C Clang handler should include root directories for projects with .hpp files in them): - call ale#assert#SetUpLinterTest('c', 'clang') - call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.c') - let g:ale_c_clang_options = '' - - AssertLinter 'clang', - \ ale#Escape('clang') - \ . ' -S -x c -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project')) - \ . ' -' - Execute(The C ClangTidy handler should include 'include' directories for projects with a Makefile): call ale#assert#SetUpLinterTest('c', 'clangtidy') call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.cpp') @@ -131,10 +93,10 @@ Execute(The C ClangTidy handler should include 'include' directories for project \ . ' %s ' \ . '-- -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include')) -Execute(The C++ GCC handler should include 'include' directories for projects with a Makefile): - call ale#assert#SetUpLinterTest('cpp', 'gcc') +Execute(The C++ cc linter should include 'include' directories for projects with a Makefile): + call ale#assert#SetUpLinterTest('cpp', 'cc') call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.cpp') - let g:ale_cpp_gcc_options = '' + let g:ale_cpp_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -143,10 +105,10 @@ Execute(The C++ GCC handler should include 'include' directories for projects wi \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include')) \ . ' -' -Execute(The C++ GCC handler should include 'include' directories for projects with a configure file): - call ale#assert#SetUpLinterTest('cpp', 'gcc') +Execute(The C++ cc linter should include 'include' directories for projects with a configure file): + call ale#assert#SetUpLinterTest('cpp', 'cc') call ale#test#SetFilename('../test_c_projects/configure_project/subdir/file.cpp') - let g:ale_cpp_gcc_options = '' + let g:ale_cpp_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -155,10 +117,10 @@ Execute(The C++ GCC handler should include 'include' directories for projects wi \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include')) \ . ' -' -Execute(The C++ GCC handler should include root directories for projects with .h files in them): - call ale#assert#SetUpLinterTest('cpp', 'gcc') +Execute(The C++ cc linter should include root directories for projects with .h files in them): + call ale#assert#SetUpLinterTest('cpp', 'cc') call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.cpp') - let g:ale_cpp_gcc_options = '' + let g:ale_cpp_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -167,10 +129,10 @@ Execute(The C++ GCC handler should include root directories for projects with .h \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project')) \ . ' -' -Execute(The C++ GCC handler should include root directories for projects with .hpp files in them): - call ale#assert#SetUpLinterTest('cpp', 'gcc') +Execute(The C++ cc linter should include root directories for projects with .hpp files in them): + call ale#assert#SetUpLinterTest('cpp', 'cc') call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.cpp') - let g:ale_cpp_gcc_options = '' + let g:ale_cpp_cc_options = '' AssertLinter 'gcc', \ ale#Escape('gcc') @@ -179,54 +141,6 @@ Execute(The C++ GCC handler should include root directories for projects with .h \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project')) \ . ' -' -Execute(The C++ Clang handler should include 'include' directories for projects with a Makefile): - call ale#assert#SetUpLinterTest('cpp', 'clang') - call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.cpp') - let g:ale_cpp_clang_options = '' - - AssertLinter 'clang++', - \ ale#Escape('clang++') - \ . ' -S -x c++ -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include')) - \ . ' -' - -Execute(The C++ Clang handler should include 'include' directories for projects with a configure file): - call ale#assert#SetUpLinterTest('cpp', 'clang') - call ale#test#SetFilename('../test_c_projects/configure_project/subdir/file.cpp') - let g:ale_cpp_clang_options = '' - - AssertLinter 'clang++', - \ ale#Escape('clang++') - \ . ' -S -x c++ -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include')) - \ . ' -' - -Execute(The C++ Clang handler should include root directories for projects with .h files in them): - call ale#assert#SetUpLinterTest('cpp', 'clang') - call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.cpp') - let g:ale_cpp_clang_options = '' - - AssertLinter 'clang++', - \ ale#Escape('clang++') - \ . ' -S -x c++ -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project')) - \ . ' -' - -Execute(The C++ Clang handler should include root directories for projects with .hpp files in them): - call ale#assert#SetUpLinterTest('cpp', 'clang') - call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.cpp') - let g:ale_cpp_clang_options = '' - - AssertLinter 'clang++', - \ ale#Escape('clang++') - \ . ' -S -x c++ -fsyntax-only' - \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir')) - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project')) - \ . ' -' - Execute(The C++ ClangTidy handler should include json folders for projects with suitable build directory in them): call ale#assert#SetUpLinterTest('cpp', 'clangtidy') call ale#test#SetFilename('../test_c_projects/json_project/subdir/file.cpp') diff --git a/test/command_callback/test_cpp_clang_command_callbacks.vader b/test/command_callback/test_cpp_clang_command_callbacks.vader deleted file mode 100644 index 7d5fe989..00000000 --- a/test/command_callback/test_cpp_clang_command_callbacks.vader +++ /dev/null @@ -1,37 +0,0 @@ -Before: - Save g:ale_c_parse_makefile - let g:ale_c_parse_makefile = 0 - - let g:get_cflags_return_value = '' - - runtime autoload/ale/c.vim - - function! ale#c#GetCFlags(buffer, output) abort - return g:get_cflags_return_value - endfunction - - call ale#assert#SetUpLinterTest('cpp', 'clang') - let b:command_tail = ' -S -x c++ -fsyntax-only -iquote' - \ . ' ' . ale#Escape(getcwd()) - \ . ' -std=c++14 -Wall -' - -After: - unlet! g:get_cflags_return_value - unlet! b:command_tail - - runtime autoload/ale/c.vim - - call ale#assert#TearDownLinterTest() - -Execute(The executable should be configurable): - AssertLinter 'clang++', ale#Escape('clang++') . b:command_tail - - let b:ale_cpp_clang_executable = 'foobar' - - AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail - -Execute(The -std flag should be replaced by parsed C flags): - let b:command_tail = substitute(b:command_tail, 'c++14', 'c++11 ', '') - let g:get_cflags_return_value = '-std=c++11' - - AssertLinter 'clang++', ale#Escape('clang++') . b:command_tail diff --git a/test/command_callback/test_cpp_gcc_command_callbacks.vader b/test/command_callback/test_cpp_gcc_command_callbacks.vader index 9a64e6a4..930cc68a 100644 --- a/test/command_callback/test_cpp_gcc_command_callbacks.vader +++ b/test/command_callback/test_cpp_gcc_command_callbacks.vader @@ -1,16 +1,26 @@ Before: Save g:ale_c_parse_makefile + Save g:ale_history_enabled + let g:ale_c_parse_makefile = 0 + let g:ale_history_enabled = 0 let g:get_cflags_return_value = '' + let g:executable_map = {} runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim + + function! ale#engine#IsExecutable(buffer, executable) abort + return has_key(g:executable_map, a:executable) + endfunction function! ale#c#GetCFlags(buffer, output) abort return g:get_cflags_return_value endfunction - call ale#assert#SetUpLinterTest('cpp', 'gcc') + call ale#assert#SetUpLinterTest('cpp', 'cc') + let b:command_tail = ' -S -x c++' \ . ' -o ' . (has('win32') ? 'nul': '/dev/null') \ . ' -iquote ' . ale#Escape(getcwd()) @@ -18,18 +28,25 @@ Before: After: unlet! g:get_cflags_return_value + unlet! g:executable_map unlet! b:command_tail runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim call ale#assert#TearDownLinterTest() +Execute(clang++ should be used instead of gcc, if available): + let g:executable_map = {'clang++': 1} + + AssertLinter 'clang++', [ale#Escape('clang++') . b:command_tail] + Execute(The executable should be configurable): - AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail + AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail] - let b:ale_cpp_gcc_executable = 'foobar' + let b:ale_cpp_cc_executable = 'foobar' - AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail + AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail] Execute(The -std flag should be replaced by parsed C flags): let b:command_tail = substitute(b:command_tail, 'c++14', 'c++11 ', '') diff --git a/test/fixers/test_clangtidy_fixer_callback.vader b/test/fixers/test_clangtidy_fixer_callback.vader index 68416b36..ca08e6bc 100644 --- a/test/fixers/test_clangtidy_fixer_callback.vader +++ b/test/fixers/test_clangtidy_fixer_callback.vader @@ -1,8 +1,19 @@ Before: + Save g:ale_c_build_dir Save g:ale_c_clangtidy_executable + Save g:ale_c_clangtidy_checks + Save g:ale_c_clangtidy_extra_options + Save g:ale_cpp_clangtidy_executable + Save g:ale_cpp_clangtidy_checks + Save g:ale_cpp_clangtidy_extra_options " Use an invalid global executable, so we don't match it. let g:ale_c_clangtidy_executable = 'xxxinvalid' + let g:ale_c_clangtidy_checks = [] + let g:ale_c_clangtidy_extra_options = '' + let g:ale_cpp_clangtidy_executable = 'xxxinvalidpp' + let g:ale_cpp_clangtidy_checks = [] + let g:ale_cpp_clangtidy_extra_options = '' let g:ale_c_build_dir = '' call ale#test#SetDirectory('/testplugin/test/fixers') @@ -36,16 +47,3 @@ Execute(The clangtidy callback should include any additional options): \ . ' -fix -fix-errors --some-option %t', \ }, \ ale#fixers#clangtidy#Fix(bufnr('')) - -Execute(The clangtidy callback should support cpp files): - call ale#test#SetFilename('c_paths/dummy.cpp') - let g:ale_cpp_clangtidy_executable = 'invalidpp' - set filetype=cpp " The test fails without this - - AssertEqual - \ { - \ 'read_temporary_file': 1, - \ 'command': ale#Escape(g:ale_cpp_clangtidy_executable) - \ . ' -fix -fix-errors %t', - \ }, - \ ale#fixers#clangtidy#Fix(bufnr(''))