summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/stale.yml5
-rw-r--r--ale_linters/asciidoc/languagetool.vim5
-rw-r--r--ale_linters/c/cc.vim53
-rw-r--r--ale_linters/c/clang.vim24
-rw-r--r--ale_linters/c/gcc.vim28
-rw-r--r--ale_linters/cpp/cc.vim53
-rw-r--r--ale_linters/cpp/clang.vim24
-rw-r--r--ale_linters/cpp/gcc.vim29
-rw-r--r--ale_linters/elixir/credo.vim2
-rw-r--r--ale_linters/markdown/markdownlint.vim13
-rw-r--r--ale_linters/ocaml/ols.vim2
-rw-r--r--ale_linters/reason/ols.vim2
-rw-r--r--ale_linters/sh/shell.vim2
-rw-r--r--ale_linters/swift/swiftformat.vim62
-rw-r--r--autoload/ale/assert.vim2
-rw-r--r--autoload/ale/c.vim69
-rw-r--r--autoload/ale/definition.vim8
-rw-r--r--autoload/ale/engine.vim130
-rw-r--r--autoload/ale/fix.vim25
-rw-r--r--autoload/ale/fix/registry.vim5
-rw-r--r--autoload/ale/fixers/remark_lint.vim24
-rw-r--r--autoload/ale/fixers/standard.vim2
-rw-r--r--autoload/ale/handlers/sh.vim17
-rw-r--r--autoload/ale/hover.vim5
-rw-r--r--autoload/ale/linter.vim183
-rw-r--r--autoload/ale/lsp.vim4
-rw-r--r--autoload/ale/lsp_linter.vim2
-rw-r--r--autoload/ale/test.vim4
-rw-r--r--doc/ale-c.txt117
-rw-r--r--doc/ale-cpp.txt125
-rw-r--r--doc/ale-markdown.txt11
-rw-r--r--doc/ale-supported-languages-and-tools.txt10
-rw-r--r--doc/ale.txt35
-rw-r--r--plugin/ale.vim24
-rwxr-xr-xrun-tests8
-rw-r--r--supported-tools.md2
-rw-r--r--test/command_callback/test_c_cc_command_callbacks.vader55
-rw-r--r--test/command_callback/test_c_clang_command_callbacks.vader20
-rw-r--r--test/command_callback/test_c_gcc_command_callbacks.vader22
-rw-r--r--test/command_callback/test_c_import_paths.vader154
-rw-r--r--test/command_callback/test_cpp_clang_command_callbacks.vader19
-rw-r--r--test/command_callback/test_cpp_gcc_command_callbacks.vader43
-rw-r--r--test/command_callback/test_elixir_credo.vader12
-rw-r--r--test/command_callback/test_markdown_markdownlint_command_callback.vader13
-rw-r--r--test/command_callback/test_swift_swiftformat_command_callbacks.vader25
-rw-r--r--test/fix/test_ale_fix.vader110
-rw-r--r--test/fixers/test_clangtidy_fixer_callback.vader24
-rw-r--r--test/fixers/test_eslint_fixer_callback.vader4
-rw-r--r--test/fixers/test_prettier_eslint_fixer.callback.vader3
-rw-r--r--test/fixers/test_prettier_fixer_callback.vader3
-rw-r--r--test/fixers/test_remark_lint_fixer_callback.vader24
-rw-r--r--test/fixers/test_standard_fixer_callback.vader4
-rw-r--r--test/handler/test_glslang_handler.vader3
-rw-r--r--test/handler/test_standard_handler.vader8
-rw-r--r--test/handler/test_swiftformat_handler.vader28
-rw-r--r--test/lsp/test_did_save_event.vader4
-rw-r--r--test/lsp/test_lsp_command_formatting.vader10
-rw-r--r--test/lsp/test_lsp_custom_request.vader1
-rw-r--r--test/lsp/test_lsp_startup.vader10
-rw-r--r--test/sign/test_linting_sets_signs.vader2
-rw-r--r--test/sign/test_sign_placement.vader2
-rw-r--r--test/test_c_flag_parsing.vader16
-rw-r--r--test/test_c_projects/makefile_project/args3
-rw-r--r--test/test_c_projects/makefile_project/subdir/args1
-rw-r--r--test/test_command_chain.vader73
-rw-r--r--test/test_engine_invocation.vader108
-rw-r--r--test/test_go_to_definition.vader2
-rw-r--r--test/test_linter_defintion_processing.vader387
-rw-r--r--test/test_shell_detection.vader10
-rw-r--r--test/test_temporary_file_management.vader2
70 files changed, 884 insertions, 1437 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: >
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/ale_linters/c/cc.vim b/ale_linters/c/cc.vim
new file mode 100644
index 00000000..6d920ab0
--- /dev/null
+++ b/ale_linters/c/cc.vim
@@ -0,0 +1,53 @@
+" Author: w0rp <devw0rp@gmail.com>
+" Description: A C compiler linter for C files with gcc/clang, etc.
+
+call ale#Set('c_cc_executable', '<auto>')
+call ale#Set('c_cc_options', '-std=c11 -Wall')
+
+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# '<auto>'
+ 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_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('c', {
+\ 'name': 'cc',
+\ 'aliases': ['gcc', 'clang'],
+\ 'output_stream': 'stderr',
+\ '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 681101fc..00000000
--- a/ale_linters/c/clang.vim
+++ /dev/null
@@ -1,24 +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)
-
- " -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')) . ' -'
-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/c/gcc.vim b/ale_linters/c/gcc.vim
deleted file mode 100644
index 1df1018e..00000000
--- a/ale_linters/c/gcc.vim
+++ /dev/null
@@ -1,28 +0,0 @@
-" Author: w0rp <devw0rp@gmail.com>
-" Description: gcc linter for c files
-
-call ale#Set('c_gcc_executable', 'gcc')
-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)
-
- " -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(ale#Var(a:buffer, 'c_gcc_options')) . ' -'
-endfunction
-
-call ale#linter#Define('c', {
-\ 'name': 'gcc',
-\ 'output_stream': 'stderr',
-\ 'executable': {b -> ale#Var(b, 'c_gcc_executable')},
-\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#gcc#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 <devw0rp@gmail.com>
+" Description: A C++ compiler linter for C++ files with gcc/clang, etc.
+
+call ale#Set('cpp_cc_executable', '<auto>')
+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# '<auto>'
+ 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 e48291eb..00000000
--- a/ale_linters/cpp/clang.vim
+++ /dev/null
@@ -1,24 +0,0 @@
-" Author: Tomota Nakamura <https://github.com/tomotanakamura>
-" 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)
-
- " -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')) . ' -'
-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 108d6d70..00000000
--- a/ale_linters/cpp/gcc.vim
+++ /dev/null
@@ -1,29 +0,0 @@
-" Author: geam <mdelage@student.42.fr>
-" 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)
-
- " -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(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'
-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/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/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 <tylucaskelley@gmail.com>
" 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/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/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 <devw0rp@gmail.com>
-" 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')
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 <https://github.com/klaaspieter>
+" 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/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/c.vim b/autoload/ale/c.vim
index 39892d42..5cf4c690 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')
@@ -61,10 +69,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)
@@ -76,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'
@@ -111,7 +168,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
@@ -125,7 +182,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 !s:CanParseMakefile(a:buffer)
return v:null
endif
@@ -335,9 +392,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
@@ -349,7 +404,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)
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/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 <blyoa110@gmail.com>
+" 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/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/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')
+ 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
+ " 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/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/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
-
- let l:obj.language_callback = get(a:linter, 'language_callback')
+ " Default to using the filetype as the language.
+ let l:obj.language = get(a:linter, 'language', a:filetype)
- 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
+endfunction
+
+function! ale#linter#GetLanguage(buffer, linter) abort
+ let l:Language = a:linter.language
- return type(l:Address) is v:t_func
- \ ? l:Address(a:buffer)
- \ : l:Address
+ return type(l:Language) is v:t_func ? l:Language(a:buffer) : l:Language
endfunction
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/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-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: `'<auto>'`
+
+ This variable can be changed to use a different executable for a C compiler.
- This variable can be changed to use a different executable for clang.
+ 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.
===============================================================================
@@ -295,25 +334,6 @@ g:ale_c_flawfinder_error_severity *g:ale_c_flawfinder_error_severity*
===============================================================================
-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*
g:ale_c_uncrustify_executable *g:ale_c_uncrustify_executable*
@@ -333,35 +353,4 @@ g:ale_c_uncrustify_options *g:ale_c_uncrustify_options*
===============================================================================
-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: `'<auto>'`
+
+ This variable can be changed to use a different executable for a C++ compiler.
- This variable can be changed to use a different executable for clang.
+ 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.
===============================================================================
@@ -107,6 +127,25 @@ g:ale_cpp_clangcheck_options *g:ale_cpp_clangcheck_options*
===============================================================================
+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*
See |ale-c-clangformat| for information about the available options.
@@ -296,60 +335,10 @@ g:ale_cpp_flawfinder_options *g:ale-cpp-flawfinder*
===============================================================================
-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-markdown.txt b/doc/ale-markdown.txt
index 4e27eb91..99848878 100644
--- a/doc/ale-markdown.txt
+++ b/doc/ale-markdown.txt
@@ -3,6 +3,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*
g:ale_markdown_mdl_executable *g:ale_markdown_mdl_executable*
diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt
index 6d495fa9..e1a91b20 100644
--- a/doc/ale-supported-languages-and-tools.txt
+++ b/doc/ale-supported-languages-and-tools.txt
@@ -22,6 +22,7 @@ Notes:
* `drafter`
* AsciiDoc
* `alex`!!
+ * `languagetool`!!
* `proselint`
* `redpen`
* `textlint`
@@ -48,7 +49,7 @@ Notes:
* C
* `astyle`
* `ccls`
- * `clang`
+ * `clang` (`cc`)
* `clangd`
* `clang-format`
* `clangtidy`!!
@@ -56,7 +57,7 @@ Notes:
* `cpplint`!!
* `cquery`
* `flawfinder`
- * `gcc`
+ * `gcc` (`cc`)
* `uncrustify`
* C#
* `csc`!!
@@ -66,7 +67,7 @@ Notes:
* C++ (filetype cpp)
* `astyle`
* `ccls`
- * `clang`
+ * `clang` (`cc`)
* `clangcheck`!!
* `clangd`
* `clang-format`
@@ -76,7 +77,7 @@ Notes:
* `cpplint`!!
* `cquery`
* `flawfinder`
- * `gcc`
+ * `gcc` (`cc`)
* `uncrustify`
* Chef
* `cookstyle`
@@ -454,6 +455,7 @@ Notes:
* Swift
* `sourcekit-lsp`
* `swiftformat`
+ * `swift-format`
* `swiftlint`
* Tcl
* `nagelfar`!!
diff --git a/doc/ale.txt b/doc/ale.txt
index 1951d7bd..df55b544 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
@@ -2320,16 +2323,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|
@@ -2343,9 +2345,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|
@@ -2353,9 +2356,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|
@@ -2503,6 +2504,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|
@@ -2809,7 +2811,13 @@ ALEGoToDefinition `<options>` *ALEGoToDefinition*
command. Otherwise, Vim will refuse to leave the buffer you're jumping from
unless you have saved your edits.
- A plug mapping `<Plug>(ale_go_to_definition)` is defined for this command.
+ The following Plug mappings are defined for this command, which correspond
+ to the following commands.
+
+ `<Plug>(ale_go_to_definition)` - `:ALEGoToDefinition`
+ `<Plug>(ale_go_to_definition_in_tab)` - `:ALEGoToDefinition -tab`
+ `<Plug>(ale_go_to_definition_in_split)` - `:ALEGoToDefinition -split`
+ `<Plug>(ale_go_to_definition_in_vsplit)` - `:ALEGoToDefinition -vsplit`
ALEGoToTypeDefinition *ALEGoToTypeDefinition*
@@ -2831,8 +2839,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 `<Plug>(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.
+
+ `<Plug>(ale_go_to_type_definition)` - `:ALEGoToTypeDefinition`
+ `<Plug>(ale_go_to_type_definition_in_tab)` - `:ALEGoToTypeDefinition -tab`
+ `<Plug>(ale_go_to_type_definition_in_split)` - `:ALEGoToTypeDefinition -split`
+ `<Plug>(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('', <f-args>)
-" 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', <f-args>)
-" 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 <silent> <Plug>(ale_lint) :ALELint<Return>
nnoremap <silent> <Plug>(ale_detail) :ALEDetail<Return>
nnoremap <silent> <Plug>(ale_fix) :ALEFix<Return>
nnoremap <silent> <Plug>(ale_go_to_definition) :ALEGoToDefinition<Return>
+nnoremap <silent> <Plug>(ale_go_to_definition_in_tab) :ALEGoToDefinition -tab<Return>
+nnoremap <silent> <Plug>(ale_go_to_definition_in_split) :ALEGoToDefinition -split<Return>
+nnoremap <silent> <Plug>(ale_go_to_definition_in_vsplit) :ALEGoToDefinition -vsplit<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition) :ALEGoToTypeDefinition<Return>
+nnoremap <silent> <Plug>(ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinition -tab<Return>
+nnoremap <silent> <Plug>(ale_go_to_type_definition_in_split) :ALEGoToTypeDefinition -split<Return>
+nnoremap <silent> <Plug>(ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionIn -vsplit<Return>
nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return>
@@ -278,14 +274,6 @@ inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return>
nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<Return>
-" Deprecated <Plug> mappings
-nnoremap <silent> <Plug>(ale_go_to_definition_in_tab) :ALEGoToDefinitionInTab<Return>
-nnoremap <silent> <Plug>(ale_go_to_definition_in_split) :ALEGoToDefinitionInSplit<Return>
-nnoremap <silent> <Plug>(ale_go_to_definition_in_vsplit) :ALEGoToDefinitionInVSplit<Return>
-nnoremap <silent> <Plug>(ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinitionInTab<Return>
-nnoremap <silent> <Plug>(ale_go_to_type_definition_in_split) :ALEGoToTypeDefinitionInSplit<Return>
-nnoremap <silent> <Plug>(ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionInVSplit<Return>
-
" Set up autocmd groups now.
call ale#events#Init()
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/supported-tools.md b/supported-tools.md
index 7b884ff5..f15bd79a 100644
--- a/supported-tools.md
+++ b/supported-tools.md
@@ -31,6 +31,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/)
@@ -463,6 +464,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_c_cc_command_callbacks.vader b/test/command_callback/test_c_cc_command_callbacks.vader
new file mode 100644
index 00000000..9d71d941
--- /dev/null
+++ b/test/command_callback/test_c_cc_command_callbacks.vader
@@ -0,0 +1,55 @@
+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('c', 'cc')
+
+ let b:command_tail = ' -S -x c'
+ \ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
+ \ . ' -iquote ' . ale#Escape(getcwd())
+ \ . ' -std=c11 -Wall -'
+
+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_cc_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_c_clang_command_callbacks.vader b/test/command_callback/test_c_clang_command_callbacks.vader
deleted file mode 100644
index b8c02e4d..00000000
--- a/test/command_callback/test_c_clang_command_callbacks.vader
+++ /dev/null
@@ -1,20 +0,0 @@
-Before:
- Save g:ale_c_parse_makefile
- let g:ale_c_parse_makefile = 0
-
- call ale#assert#SetUpLinterTest('c', 'clang')
- let b:command_tail = ' -S -x c -fsyntax-only -iquote'
- \ . ' ' . ale#Escape(getcwd())
- \ . ' -std=c11 -Wall -'
-
-After:
- unlet! b:command_tail
-
- 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]
diff --git a/test/command_callback/test_c_gcc_command_callbacks.vader b/test/command_callback/test_c_gcc_command_callbacks.vader
deleted file mode 100644
index 2dbb8b7c..00000000
--- a/test/command_callback/test_c_gcc_command_callbacks.vader
+++ /dev/null
@@ -1,22 +0,0 @@
-Before:
- Save g:ale_c_parse_makefile
- let g:ale_c_parse_makefile = 0
-
- call ale#assert#SetUpLinterTest('c', 'gcc')
-
- let b:command_tail = ' -S -x c'
- \ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
- \ . ' -iquote ' . ale#Escape(getcwd())
- \ . ' -std=c11 -Wall -'
-
-After:
- call ale#assert#TearDownLinterTest()
-
- unlet! b:command_tail
-
-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]
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 e96fd8e7..00000000
--- a/test/command_callback/test_cpp_clang_command_callbacks.vader
+++ /dev/null
@@ -1,19 +0,0 @@
-Before:
- Save g:ale_c_parse_makefile
- let g:ale_c_parse_makefile = 0
-
- 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! b:command_tail
- 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
diff --git a/test/command_callback/test_cpp_gcc_command_callbacks.vader b/test/command_callback/test_cpp_gcc_command_callbacks.vader
index cfa4ecc0..930cc68a 100644
--- a/test/command_callback/test_cpp_gcc_command_callbacks.vader
+++ b/test/command_callback/test_cpp_gcc_command_callbacks.vader
@@ -1,20 +1,55 @@
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', 'cc')
- call ale#assert#SetUpLinterTest('cpp', 'gcc')
let b:command_tail = ' -S -x c++'
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(getcwd())
\ . ' -std=c++14 -Wall -'
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 ', '')
+ let g:get_cflags_return_value = '-std=c++11'
+
+ AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
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
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'
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/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader
index c3dd20e4..53079d16 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 = {}
@@ -82,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'}
@@ -206,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
@@ -814,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/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(''))
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/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(''))
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(''))
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/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',
+ \ ])
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 ec3b4120..e99e1dad 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
@@ -18,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/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'']')
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
diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader
index 8ae6f9dc..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'
@@ -364,5 +365,16 @@ 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):
+ 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
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',
- \}
-
- AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp
-
-Execute(PreProcess should accept let you specify the language as just a string):
- let g:linter = {
- \ 'name': 'x',
- \ 'lsp': 'socket',
- \ 'address_callback': 'X',
+ \ 'address': 'X',
\ 'language': 'foobar',
- \ 'project_root_callback': 'x',
+ \ 'project_root': 'x',
\}
- AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language_callback(0)
+ AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp
-Execute(PreProcess should complain about using language and language_callback together):
+Execute(PreProcess should accept let you specify the `language` as a Function):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
- \ 'address_callback': 'X',
- \ 'language': 'x',
- \ 'language_callback': 'x',
- \ 'project_root_callback': 'x',
+ \ 'address': 'X',
+ \ 'language': {-> 'foobar'},
+ \ 'project_root': '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',
- \}
-
- AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language_callback(0)
-
-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',
+ \ 'address': 'X',
+ \ 'project_root': 'x',
\}
- AssertEqual 'foo', ale#linter#PreProcess('testft', g:linter).language_callback(0)
+ AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language
-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):
- AssertThrows call ale#linter#PreProcess('testft', {
- \ 'name': 'foo',
- \ 'lsp': 'socket',
- \ 'address_callback': '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):
+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',
+ \ '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_shell_detection.vader b/test/test_shell_detection.vader
index 6452287f..697054d0 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#handlers#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
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()