Compare commits
15 commits
Author | SHA1 | Date | |
---|---|---|---|
|
a94f7aaa7e | ||
|
21c4b9033a | ||
|
f382afbe23 | ||
|
4da8c3607d | ||
|
c3844db973 | ||
|
8a374a69a3 | ||
|
68bae8a1d1 | ||
|
b8dcdc984b | ||
|
c6d3d646ac | ||
|
c8de2d9766 | ||
|
6d50074984 | ||
|
6b87dd24ee | ||
|
11fafbfd66 | ||
|
06c3ee61e4 | ||
|
5a88395bbb |
35 changed files with 465 additions and 180 deletions
|
@ -6,4 +6,5 @@ call ale#linter#Define('go', {
|
||||||
\ 'executable': 'gosimple',
|
\ 'executable': 'gosimple',
|
||||||
\ 'command': 'gosimple %t',
|
\ 'command': 'gosimple %t',
|
||||||
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
|
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
|
||||||
|
\ 'output_stream': 'both'
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -6,4 +6,5 @@ call ale#linter#Define('go', {
|
||||||
\ 'executable': 'staticcheck',
|
\ 'executable': 'staticcheck',
|
||||||
\ 'command': 'staticcheck %t',
|
\ 'command': 'staticcheck %t',
|
||||||
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
|
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
|
||||||
|
\ 'output_stream': 'both'
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -14,17 +14,9 @@ endfunction
|
||||||
|
|
||||||
function! ale_linters#javascript#standard#GetCommand(buffer) abort
|
function! ale_linters#javascript#standard#GetCommand(buffer) abort
|
||||||
let l:executable = ale_linters#javascript#standard#GetExecutable(a:buffer)
|
let l:executable = ale_linters#javascript#standard#GetExecutable(a:buffer)
|
||||||
|
|
||||||
if ale#Has('win32') && l:executable =~? '\.js$'
|
|
||||||
" .js files have to be executed with Node on Windows.
|
|
||||||
let l:head = 'node ' . ale#Escape(l:executable)
|
|
||||||
else
|
|
||||||
let l:head = ale#Escape(l:executable)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:options = ale#Var(a:buffer, 'javascript_standard_options')
|
let l:options = ale#Var(a:buffer, 'javascript_standard_options')
|
||||||
|
|
||||||
return l:head
|
return ale#node#Executable(a:buffer, l:executable)
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' --stdin %s'
|
\ . ' --stdin %s'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -17,18 +17,10 @@ if !exists('g:ale_sh_shell_default_shell')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
function! ale_linters#sh#shell#GetExecutable(buffer) abort
|
function! ale_linters#sh#shell#GetExecutable(buffer) abort
|
||||||
let l:banglines = getbufline(a:buffer, 1)
|
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
|
||||||
|
|
||||||
" Take the shell executable from the hashbang, if we can.
|
if !empty(l:shell_type)
|
||||||
if len(l:banglines) == 1 && l:banglines[0] =~# '^#!'
|
return l:shell_type
|
||||||
" Remove options like -e, etc.
|
|
||||||
let l:line = substitute(l:banglines[0], '--\?[a-zA-Z0-9]\+', '', 'g')
|
|
||||||
|
|
||||||
for l:possible_shell in ['bash', 'tcsh', 'csh', 'zsh', 'sh']
|
|
||||||
if l:line =~# l:possible_shell . '\s*$'
|
|
||||||
return l:possible_shell
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#Var(a:buffer, 'sh_shell_default_shell')
|
return ale#Var(a:buffer, 'sh_shell_default_shell')
|
||||||
|
|
|
@ -19,25 +19,35 @@ function! ale_linters#sh#shellcheck#GetExecutable(buffer) abort
|
||||||
return ale#Var(a:buffer, 'sh_shellcheck_executable')
|
return ale#Var(a:buffer, 'sh_shellcheck_executable')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GetDialectArgument() abort
|
function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
|
||||||
if exists('b:is_bash') && b:is_bash
|
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
|
||||||
return '-s bash'
|
|
||||||
elseif exists('b:is_sh') && b:is_sh
|
if !empty(l:shell_type)
|
||||||
return '-s sh'
|
return l:shell_type
|
||||||
elseif exists('b:is_kornshell') && b:is_kornshell
|
endif
|
||||||
return '-s ksh'
|
|
||||||
|
" If there's no hashbang, try using Vim's buffer variables.
|
||||||
|
if get(b:, 'is_bash')
|
||||||
|
return 'bash'
|
||||||
|
elseif get(b:, 'is_sh')
|
||||||
|
return 'sh'
|
||||||
|
elseif get(b:, 'is_kornshell')
|
||||||
|
return 'ksh'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#sh#shellcheck#GetCommand(buffer) abort
|
function! ale_linters#sh#shellcheck#GetCommand(buffer) abort
|
||||||
|
let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
|
||||||
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
|
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
|
||||||
|
let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
|
||||||
|
|
||||||
return ale_linters#sh#shellcheck#GetExecutable(a:buffer)
|
return ale_linters#sh#shellcheck#GetExecutable(a:buffer)
|
||||||
\ . ' ' . ale#Var(a:buffer, 'sh_shellcheck_options')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' ' . (!empty(l:exclude_option) ? '-e ' . l:exclude_option : '')
|
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
|
||||||
\ . ' ' . s:GetDialectArgument() . ' -f gcc -'
|
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
|
||||||
|
\ . ' -f gcc -'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('sh', {
|
call ale#linter#Define('sh', {
|
||||||
|
|
|
@ -48,6 +48,7 @@ function! ale#ShouldDoNothing(buffer) abort
|
||||||
\ || ale#util#InSandbox()
|
\ || ale#util#InSandbox()
|
||||||
\ || !ale#Var(a:buffer, 'enabled')
|
\ || !ale#Var(a:buffer, 'enabled')
|
||||||
\ || ale#FileTooLarge()
|
\ || ale#FileTooLarge()
|
||||||
|
\ || getbufvar(a:buffer, '&l:statusline') =~# 'CtrlPMode.*funky'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" (delay, [linting_flag, buffer_number])
|
" (delay, [linting_flag, buffer_number])
|
||||||
|
|
|
@ -286,10 +286,6 @@ function! ale#engine#SetResults(buffer, loclist) abort
|
||||||
|
|
||||||
if g:ale_set_quickfix || g:ale_set_loclist
|
if g:ale_set_quickfix || g:ale_set_loclist
|
||||||
call ale#list#SetLists(a:buffer, a:loclist)
|
call ale#list#SetLists(a:buffer, a:loclist)
|
||||||
|
|
||||||
if l:linting_is_done
|
|
||||||
call ale#list#CloseWindowIfNeeded(a:buffer)
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if exists('*ale#statusline#Update')
|
if exists('*ale#statusline#Update')
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
scriptencoding utf-8
|
||||||
" Author: Peter Renström <renstrom.peter@gmail.com>
|
" Author: Peter Renström <renstrom.peter@gmail.com>
|
||||||
" Description: Fixing C/C++ files with clang-format.
|
" Description: Fixing C/C++ files with clang-format.
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,23 @@
|
||||||
" Description: Fixing files with eslint.
|
" Description: Fixing files with eslint.
|
||||||
|
|
||||||
function! s:FindConfig(buffer) abort
|
function! s:FindConfig(buffer) abort
|
||||||
for l:filename in [
|
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
|
||||||
\ '.eslintrc.js',
|
for l:basename in [
|
||||||
\ '.eslintrc.yaml',
|
\ '.eslintrc.js',
|
||||||
\ '.eslintrc.yml',
|
\ '.eslintrc.yaml',
|
||||||
\ '.eslintrc.json',
|
\ '.eslintrc.yml',
|
||||||
\ '.eslintrc',
|
\ '.eslintrc.json',
|
||||||
\ 'package.json',
|
\ '.eslintrc',
|
||||||
\]
|
\]
|
||||||
let l:config = ale#path#FindNearestFile(a:buffer, l:filename)
|
let l:config = ale#path#Simplify(l:path . '/' . l:basename)
|
||||||
|
|
||||||
if !empty(l:config)
|
if filereadable(l:config)
|
||||||
return l:config
|
return l:config
|
||||||
endif
|
endif
|
||||||
|
endfor
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return ''
|
return ale#path#FindNearestFile(a:buffer, 'package.json')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#fixers#eslint#Fix(buffer) abort
|
function! ale#fixers#eslint#Fix(buffer) abort
|
||||||
|
@ -28,17 +29,9 @@ function! ale#fixers#eslint#Fix(buffer) abort
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ale#Has('win32') && l:executable =~? 'eslint\.js$'
|
|
||||||
" For Windows, if we detect an eslint.js script, we need to execute
|
|
||||||
" it with node, or the file can be opened with a text editor.
|
|
||||||
let l:head = 'node ' . ale#Escape(l:executable)
|
|
||||||
else
|
|
||||||
let l:head = ale#Escape(l:executable)
|
|
||||||
endif
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': l:head
|
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||||
\ . ' --config ' . ale#Escape(l:config)
|
\ . ' -c ' . ale#Escape(l:config)
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\}
|
\}
|
||||||
|
|
|
@ -11,16 +11,8 @@ endfunction
|
||||||
function! ale#fixers#standard#Fix(buffer) abort
|
function! ale#fixers#standard#Fix(buffer) abort
|
||||||
let l:executable = ale#fixers#standard#GetExecutable(a:buffer)
|
let l:executable = ale#fixers#standard#GetExecutable(a:buffer)
|
||||||
|
|
||||||
if ale#Has('win32') && l:executable =~? 'cmd\.js$'
|
|
||||||
" For Windows, if we detect an standard.js script, we need to execute
|
|
||||||
" it with node, or the file can be opened with a text editor.
|
|
||||||
let l:head = 'node ' . ale#Escape(l:executable)
|
|
||||||
else
|
|
||||||
let l:head = ale#Escape(l:executable)
|
|
||||||
endif
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': l:head
|
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\}
|
\}
|
||||||
|
|
|
@ -15,16 +15,8 @@ endfunction
|
||||||
function! ale#fixers#stylelint#Fix(buffer) abort
|
function! ale#fixers#stylelint#Fix(buffer) abort
|
||||||
let l:executable = ale#fixers#stylelint#GetExecutable(a:buffer)
|
let l:executable = ale#fixers#stylelint#GetExecutable(a:buffer)
|
||||||
|
|
||||||
if ale#Has('win32') && l:executable =~? 'stylelint\.js$'
|
|
||||||
" For Windows, if we detect an stylelint.js script, we need to execute
|
|
||||||
" it with node, or the file can be opened with a text editor.
|
|
||||||
let l:head = 'node ' . ale#Escape(l:executable)
|
|
||||||
else
|
|
||||||
let l:head = ale#Escape(l:executable)
|
|
||||||
endif
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': l:head
|
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\}
|
\}
|
||||||
|
|
|
@ -17,17 +17,9 @@ endfunction
|
||||||
function! ale#handlers#eslint#GetCommand(buffer) abort
|
function! ale#handlers#eslint#GetCommand(buffer) abort
|
||||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||||
|
|
||||||
if ale#Has('win32') && l:executable =~? 'eslint\.js$'
|
|
||||||
" For Windows, if we detect an eslint.js script, we need to execute
|
|
||||||
" it with node, or the file can be opened with a text editor.
|
|
||||||
let l:head = 'node ' . ale#Escape(l:executable)
|
|
||||||
else
|
|
||||||
let l:head = ale#Escape(l:executable)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
|
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
|
||||||
|
|
||||||
return l:head
|
return ale#node#Executable(a:buffer, l:executable)
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' -f unix --stdin --stdin-filename %s'
|
\ . ' -f unix --stdin --stdin-filename %s'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
20
autoload/ale/handlers/sh.vim
Normal file
20
autoload/ale/handlers/sh.vim
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
|
||||||
|
" Get the shell type for a buffer, based on the hashbang line.
|
||||||
|
function! ale#handlers#sh#GetShellType(buffer) abort
|
||||||
|
let l:bang_line = get(getbufline(a:buffer, 1), 0, '')
|
||||||
|
|
||||||
|
" Take the shell executable from the hashbang, if we can.
|
||||||
|
if l:bang_line[:1] is# '#!'
|
||||||
|
" Remove options like -e, etc.
|
||||||
|
let l:command = substitute(l:bang_line, ' --\?[a-zA-Z0-9]\+', '', 'g')
|
||||||
|
|
||||||
|
for l:possible_shell in ['bash', 'tcsh', 'csh', 'zsh', 'sh']
|
||||||
|
if l:command =~# l:possible_shell . '\s*$'
|
||||||
|
return l:possible_shell
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
|
@ -25,6 +25,7 @@ let s:default_ale_linters = {
|
||||||
\ 'csh': ['shell'],
|
\ 'csh': ['shell'],
|
||||||
\ 'go': ['gofmt', 'golint', 'go vet'],
|
\ 'go': ['gofmt', 'golint', 'go vet'],
|
||||||
\ 'help': [],
|
\ 'help': [],
|
||||||
|
\ 'python': ['flake8', 'mypy', 'pylint'],
|
||||||
\ 'rust': ['cargo'],
|
\ 'rust': ['cargo'],
|
||||||
\ 'spec': [],
|
\ 'spec': [],
|
||||||
\ 'text': [],
|
\ 'text': [],
|
||||||
|
|
|
@ -56,6 +56,10 @@ function! s:FixList(list) abort
|
||||||
return l:new_list
|
return l:new_list
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:BufWinId(buffer) abort
|
||||||
|
return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
let l:title = expand('#' . a:buffer . ':p')
|
let l:title = expand('#' . a:buffer . ':p')
|
||||||
|
|
||||||
|
@ -72,7 +76,7 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
" If windows support is off, bufwinid() may not exist.
|
" If windows support is off, bufwinid() may not exist.
|
||||||
" We'll set result in the current window, which might not be correct,
|
" We'll set result in the current window, which might not be correct,
|
||||||
" but is better than nothing.
|
" but is better than nothing.
|
||||||
let l:win_id = exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
|
let l:win_id = s:BufWinId(a:buffer)
|
||||||
|
|
||||||
if has('nvim')
|
if has('nvim')
|
||||||
call setloclist(l:win_id, s:FixList(a:loclist), ' ', l:title)
|
call setloclist(l:win_id, s:FixList(a:loclist), ' ', l:title)
|
||||||
|
@ -82,13 +86,11 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:keep_open = ale#Var(a:buffer, 'keep_list_window_open')
|
|
||||||
|
|
||||||
" Open a window to show the problems if we need to.
|
" Open a window to show the problems if we need to.
|
||||||
"
|
"
|
||||||
" We'll check if the current buffer's List is not empty here, so the
|
" We'll check if the current buffer's List is not empty here, so the
|
||||||
" window will only be opened if the current buffer has problems.
|
" window will only be opened if the current buffer has problems.
|
||||||
if s:ShouldOpen(a:buffer) && (l:keep_open || !empty(a:loclist))
|
if s:ShouldOpen(a:buffer) && !empty(a:loclist)
|
||||||
let l:winnr = winnr()
|
let l:winnr = winnr()
|
||||||
let l:mode = mode()
|
let l:mode = mode()
|
||||||
let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\<c-v>"
|
let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\<c-v>"
|
||||||
|
@ -96,10 +98,10 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
|
|
||||||
if g:ale_set_quickfix
|
if g:ale_set_quickfix
|
||||||
if !ale#list#IsQuickfixOpen()
|
if !ale#list#IsQuickfixOpen()
|
||||||
execute 'copen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
|
silent! execute 'copen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
|
||||||
endif
|
endif
|
||||||
elseif g:ale_set_loclist
|
elseif g:ale_set_loclist
|
||||||
execute 'lopen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
|
silent! execute 'lopen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" If focus changed, restore it (jump to the last window).
|
" If focus changed, restore it (jump to the last window).
|
||||||
|
@ -117,10 +119,23 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" If ALE isn't currently checking for more problems, close the window if
|
||||||
|
" needed now. This check happens inside of this timer function, so
|
||||||
|
" the window can be closed reliably.
|
||||||
|
if !ale#engine#IsCheckingBuffer(a:buffer)
|
||||||
|
call s:CloseWindowIfNeeded(a:buffer)
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#list#SetLists(buffer, loclist) abort
|
function! ale#list#SetLists(buffer, loclist) abort
|
||||||
if get(g:, 'ale_set_lists_synchronously') == 1
|
if get(g:, 'ale_set_lists_synchronously') == 1
|
||||||
|
\|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
|
||||||
|
" Update lists immediately if running a test synchronously, or if the
|
||||||
|
" buffer was saved.
|
||||||
|
"
|
||||||
|
" The lists need to be updated immediately when saving a buffer so
|
||||||
|
" that we can reliably close window automatically, if so configured.
|
||||||
call s:SetListsImpl(-1, a:buffer, a:loclist)
|
call s:SetListsImpl(-1, a:buffer, a:loclist)
|
||||||
else
|
else
|
||||||
call ale#util#StartPartialTimer(
|
call ale#util#StartPartialTimer(
|
||||||
|
@ -131,7 +146,7 @@ function! ale#list#SetLists(buffer, loclist) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:CloseWindowIfNeededImpl(timer_id, buffer) abort
|
function! s:CloseWindowIfNeeded(buffer) abort
|
||||||
if ale#Var(a:buffer, 'keep_list_window_open') || !s:ShouldOpen(a:buffer)
|
if ale#Var(a:buffer, 'keep_list_window_open') || !s:ShouldOpen(a:buffer)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
@ -143,22 +158,14 @@ function! s:CloseWindowIfNeededImpl(timer_id, buffer) abort
|
||||||
if empty(getqflist())
|
if empty(getqflist())
|
||||||
cclose
|
cclose
|
||||||
endif
|
endif
|
||||||
elseif g:ale_set_loclist && empty(getloclist(0))
|
else
|
||||||
lclose
|
let l:win_id = s:BufWinId(a:buffer)
|
||||||
|
|
||||||
|
if g:ale_set_loclist && empty(getloclist(l:win_id))
|
||||||
|
lclose
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
" Ignore 'Cannot close last window' errors.
|
" Ignore 'Cannot close last window' errors.
|
||||||
catch /E444/
|
catch /E444/
|
||||||
endtry
|
endtry
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#list#CloseWindowIfNeeded(buffer) abort
|
|
||||||
if get(g:, 'ale_set_lists_synchronously') == 1
|
|
||||||
call s:CloseWindowIfNeededImpl(-1, a:buffer)
|
|
||||||
else
|
|
||||||
call ale#util#StartPartialTimer(
|
|
||||||
\ 0,
|
|
||||||
\ function('s:CloseWindowIfNeededImpl'),
|
|
||||||
\ [a:buffer],
|
|
||||||
\)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
|
@ -242,10 +242,14 @@ function! s:HandleCommandMessage(job_id, message) abort
|
||||||
call ale#lsp#HandleMessage(l:conn, a:message)
|
call ale#lsp#HandleMessage(l:conn, a:message)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:RegisterProject(conn, project_root) abort
|
function! ale#lsp#RegisterProject(conn, project_root) abort
|
||||||
if !has_key(a:conn.projects, a:project_root)
|
" Empty strings can't be used for Dictionary keys in NeoVim, due to E713.
|
||||||
|
" This appears to be a nonsensical bug in NeoVim.
|
||||||
|
let l:key = empty(a:project_root) ? '<<EMPTY>>' : a:project_root
|
||||||
|
|
||||||
|
if !has_key(a:conn.projects, l:key)
|
||||||
" Tools without project roots are ready right away, like tsserver.
|
" Tools without project roots are ready right away, like tsserver.
|
||||||
let a:conn.projects[a:project_root] = {
|
let a:conn.projects[l:key] = {
|
||||||
\ 'initialized': empty(a:project_root),
|
\ 'initialized': empty(a:project_root),
|
||||||
\ 'init_request_id': 0,
|
\ 'init_request_id': 0,
|
||||||
\ 'message_queue': [],
|
\ 'message_queue': [],
|
||||||
|
@ -253,6 +257,12 @@ function! s:RegisterProject(conn, project_root) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#lsp#GetProject(conn, project_root) abort
|
||||||
|
let l:key = empty(a:project_root) ? '<<EMPTY>>' : a:project_root
|
||||||
|
|
||||||
|
return get(a:conn.projects, l:key, {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Start a program for LSP servers which run with executables.
|
" Start a program for LSP servers which run with executables.
|
||||||
"
|
"
|
||||||
" The job ID will be returned for for the program if it ran, otherwise
|
" The job ID will be returned for for the program if it ran, otherwise
|
||||||
|
@ -285,7 +295,7 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback) abor
|
||||||
let l:conn.id = l:job_id
|
let l:conn.id = l:job_id
|
||||||
" Add the callback to the List if it's not there already.
|
" Add the callback to the List if it's not there already.
|
||||||
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
||||||
call s:RegisterProject(l:conn, a:project_root)
|
call ale#lsp#RegisterProject(l:conn, a:project_root)
|
||||||
|
|
||||||
return l:job_id
|
return l:job_id
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -311,7 +321,7 @@ function! ale#lsp#ConnectToAddress(address, project_root, callback) abort
|
||||||
let l:conn.id = a:address
|
let l:conn.id = a:address
|
||||||
" Add the callback to the List if it's not there already.
|
" Add the callback to the List if it's not there already.
|
||||||
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
||||||
call s:RegisterProject(l:conn, a:project_root)
|
call ale#lsp#RegisterProject(l:conn, a:project_root)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -344,7 +354,7 @@ function! ale#lsp#Send(conn_id, message, ...) abort
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:project = get(l:conn.projects, l:project_root, {})
|
let l:project = ale#lsp#GetProject(l:conn, l:project_root)
|
||||||
|
|
||||||
if empty(l:project)
|
if empty(l:project)
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: Functions for working with Node executables.
|
" Description: Functions for working with Node executables.
|
||||||
|
|
||||||
|
call ale#Set('windows_node_executable_path', 'node.exe')
|
||||||
|
|
||||||
" Given a buffer number, a base variable name, and a list of paths to search
|
" Given a buffer number, a base variable name, and a list of paths to search
|
||||||
" for in ancestor directories, detect the executable path for a Node program.
|
" for in ancestor directories, detect the executable path for a Node program.
|
||||||
"
|
"
|
||||||
|
@ -20,3 +22,21 @@ function! ale#node#FindExecutable(buffer, base_var_name, path_list) abort
|
||||||
|
|
||||||
return ale#Var(a:buffer, a:base_var_name . '_executable')
|
return ale#Var(a:buffer, a:base_var_name . '_executable')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Create a executable string which executes a Node.js script command with a
|
||||||
|
" Node.js executable if needed.
|
||||||
|
"
|
||||||
|
" The executable string should not be escaped before passing it to this
|
||||||
|
" function, the executable string will be escaped when returned by this
|
||||||
|
" function.
|
||||||
|
"
|
||||||
|
" The executable is only prefixed for Windows machines
|
||||||
|
function! ale#node#Executable(buffer, executable) abort
|
||||||
|
if ale#Has('win32') && a:executable =~? '\.js$'
|
||||||
|
let l:node = ale#Var(a:buffer, 'windows_node_executable_path')
|
||||||
|
|
||||||
|
return ale#Escape(l:node) . ' ' . ale#Escape(a:executable)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ale#Escape(a:executable)
|
||||||
|
endfunction
|
||||||
|
|
|
@ -184,16 +184,6 @@ function! s:GroupLoclistItems(buffer, loclist) abort
|
||||||
return l:grouped_items
|
return l:grouped_items
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#sign#SetSignColumnHighlight(has_problems) abort
|
|
||||||
highlight clear SignColumn
|
|
||||||
|
|
||||||
if a:has_problems
|
|
||||||
highlight link SignColumn ALESignColumnWithErrors
|
|
||||||
else
|
|
||||||
highlight link SignColumn ALESignColumnWithoutErrors
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UpdateLineNumbers(buffer, current_sign_list, loclist) abort
|
function! s:UpdateLineNumbers(buffer, current_sign_list, loclist) abort
|
||||||
let l:line_map = {}
|
let l:line_map = {}
|
||||||
let l:line_numbers_changed = 0
|
let l:line_numbers_changed = 0
|
||||||
|
@ -224,24 +214,32 @@ function! s:BuildSignMap(current_sign_list, grouped_items) abort
|
||||||
let l:sign_offset = g:ale_sign_offset
|
let l:sign_offset = g:ale_sign_offset
|
||||||
|
|
||||||
for [l:line, l:sign_id, l:name] in a:current_sign_list
|
for [l:line, l:sign_id, l:name] in a:current_sign_list
|
||||||
let l:sign_map[l:line] = {
|
let l:sign_info = get(l:sign_map, l:line, {
|
||||||
\ 'current_id': l:sign_id,
|
\ 'current_id_list': [],
|
||||||
\ 'current_name': l:name,
|
\ 'current_name_list': [],
|
||||||
\ 'new_id': 0,
|
\ 'new_id': 0,
|
||||||
\ 'new_name': '',
|
\ 'new_name': '',
|
||||||
\ 'items': [],
|
\ 'items': [],
|
||||||
\}
|
\})
|
||||||
|
|
||||||
|
" Increment the sign offset for new signs, by the maximum sign ID.
|
||||||
if l:sign_id > l:sign_offset
|
if l:sign_id > l:sign_offset
|
||||||
let l:sign_offset = l:sign_id
|
let l:sign_offset = l:sign_id
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Remember the sign names and IDs in separate Lists, so they are easy
|
||||||
|
" to work with.
|
||||||
|
call add(l:sign_info.current_id_list, l:sign_id)
|
||||||
|
call add(l:sign_info.current_name_list, l:name)
|
||||||
|
|
||||||
|
let l:sign_map[l:line] = l:sign_info
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
for l:group in a:grouped_items
|
for l:group in a:grouped_items
|
||||||
let l:line = l:group[0].lnum
|
let l:line = l:group[0].lnum
|
||||||
let l:sign_info = get(l:sign_map, l:line, {
|
let l:sign_info = get(l:sign_map, l:line, {
|
||||||
\ 'current_id': 0,
|
\ 'current_id_list': [],
|
||||||
\ 'current_name': '',
|
\ 'current_name_list': [],
|
||||||
\ 'new_id': 0,
|
\ 'new_id': 0,
|
||||||
\ 'new_name': '',
|
\ 'new_name': '',
|
||||||
\ 'items': [],
|
\ 'items': [],
|
||||||
|
@ -250,11 +248,18 @@ function! s:BuildSignMap(current_sign_list, grouped_items) abort
|
||||||
let l:sign_info.new_name = ale#sign#GetSignName(l:group)
|
let l:sign_info.new_name = ale#sign#GetSignName(l:group)
|
||||||
let l:sign_info.items = l:group
|
let l:sign_info.items = l:group
|
||||||
|
|
||||||
if l:sign_info.current_name isnot# l:sign_info.new_name
|
let l:index = index(
|
||||||
|
\ l:sign_info.current_name_list,
|
||||||
|
\ l:sign_info.new_name
|
||||||
|
\)
|
||||||
|
|
||||||
|
if l:index >= 0
|
||||||
|
" We have a sign with this name already, so use the same ID.
|
||||||
|
let l:sign_info.new_id = l:sign_info.current_id_list[l:index]
|
||||||
|
else
|
||||||
|
" This sign name replaces the previous name, so use a new ID.
|
||||||
let l:sign_info.new_id = l:sign_offset + 1
|
let l:sign_info.new_id = l:sign_offset + 1
|
||||||
let l:sign_offset += 1
|
let l:sign_offset += 1
|
||||||
else
|
|
||||||
let l:sign_info.new_id = l:sign_info.current_id
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:sign_map[l:line] = l:sign_info
|
let l:sign_map[l:line] = l:sign_info
|
||||||
|
@ -288,7 +293,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||||
let l:item.sign_id = l:info.new_id
|
let l:item.sign_id = l:info.new_id
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
if l:info.new_id isnot l:info.current_id
|
if index(l:info.current_id_list, l:info.new_id) < 0
|
||||||
call add(l:command_list, 'sign place '
|
call add(l:command_list, 'sign place '
|
||||||
\ . (l:info.new_id)
|
\ . (l:info.new_id)
|
||||||
\ . ' line=' . l:line_str
|
\ . ' line=' . l:line_str
|
||||||
|
@ -301,12 +306,14 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||||
|
|
||||||
" Remove signs without new IDs.
|
" Remove signs without new IDs.
|
||||||
for l:info in values(a:sign_map)
|
for l:info in values(a:sign_map)
|
||||||
if l:info.current_id && l:info.current_id isnot l:info.new_id
|
for l:current_id in l:info.current_id_list
|
||||||
call add(l:command_list, 'sign unplace '
|
if l:current_id isnot l:info.new_id
|
||||||
\ . (l:info.current_id)
|
call add(l:command_list, 'sign unplace '
|
||||||
\ . ' buffer=' . a:buffer
|
\ . l:current_id
|
||||||
\)
|
\ . ' buffer=' . a:buffer
|
||||||
endif
|
\)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
" Remove the dummy sign to close the sign column if we need to.
|
" Remove the dummy sign to close the sign column if we need to.
|
||||||
|
@ -347,7 +354,19 @@ function! ale#sign#SetSigns(buffer, loclist) abort
|
||||||
\ l:sign_map,
|
\ l:sign_map,
|
||||||
\)
|
\)
|
||||||
|
|
||||||
|
" Change the sign column color if the option is on.
|
||||||
|
if g:ale_change_sign_column_color && !empty(a:loclist)
|
||||||
|
highlight clear SignColumn
|
||||||
|
highlight link SignColumn ALESignColumnWithErrors
|
||||||
|
endif
|
||||||
|
|
||||||
for l:command in l:command_list
|
for l:command in l:command_list
|
||||||
silent! execute l:command
|
silent! execute l:command
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
" Reset the sign column color when there are no more errors.
|
||||||
|
if g:ale_change_sign_column_color && empty(a:loclist)
|
||||||
|
highlight clear SignColumn
|
||||||
|
highlight link SignColumn ALESignColumnWithoutErrors
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
16
doc/ale.txt
16
doc/ale.txt
|
@ -918,6 +918,22 @@ b:ale_warn_about_trailing_whitespace *b:ale_warn_about_trailing_whitespace*
|
||||||
This option may be configured on a per buffer basis.
|
This option may be configured on a per buffer basis.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_windows_node_executable_path *g:ale_windows_node_executable_path*
|
||||||
|
*b:ale_windows_node_executable_path*
|
||||||
|
|
||||||
|
Type: |String|
|
||||||
|
Default: `'node.exe'`
|
||||||
|
|
||||||
|
This variable is used as the path to the executable to use for executing
|
||||||
|
scripts with Node.js on Windows.
|
||||||
|
|
||||||
|
For Windows, any file with a `.js` file extension needs to be executed with
|
||||||
|
the node executable explicitly. Otherwise, Windows could try and open the
|
||||||
|
scripts with other applications, like a text editor. Therefore, these
|
||||||
|
scripts are executed with whatever executable is configured with this
|
||||||
|
setting.
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
3.1. Highlights *ale-highlights*
|
3.1. Highlights *ale-highlights*
|
||||||
|
|
||||||
|
|
47
test/command_callback/test_shellcheck_command_callback.vader
Normal file
47
test/command_callback/test_shellcheck_command_callback.vader
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
Before:
|
||||||
|
Save g:ale_sh_shellcheck_exclusions
|
||||||
|
Save g:ale_sh_shellcheck_executable
|
||||||
|
Save g:ale_sh_shellcheck_options
|
||||||
|
|
||||||
|
unlet! g:ale_sh_shellcheck_exclusions
|
||||||
|
unlet! g:ale_sh_shellcheck_executable
|
||||||
|
unlet! g:ale_sh_shellcheck_options
|
||||||
|
|
||||||
|
runtime ale_linters/sh/shellcheck.vim
|
||||||
|
|
||||||
|
After:
|
||||||
|
Restore
|
||||||
|
|
||||||
|
unlet! b:ale_sh_shellcheck_exclusions
|
||||||
|
unlet! b:ale_sh_shellcheck_executable
|
||||||
|
unlet! b:ale_sh_shellcheck_options
|
||||||
|
unlet! b:is_bash
|
||||||
|
|
||||||
|
call ale#linter#Reset()
|
||||||
|
|
||||||
|
Execute(The default shellcheck command should be correct):
|
||||||
|
AssertEqual
|
||||||
|
\ 'shellcheck -f gcc -',
|
||||||
|
\ ale_linters#sh#shellcheck#GetCommand(bufnr(''))
|
||||||
|
|
||||||
|
Execute(The shellcheck command should accept options):
|
||||||
|
let b:ale_sh_shellcheck_options = '--foobar'
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ 'shellcheck --foobar -f gcc -',
|
||||||
|
\ ale_linters#sh#shellcheck#GetCommand(bufnr(''))
|
||||||
|
|
||||||
|
Execute(The shellcheck command should accept options and exclusions):
|
||||||
|
let b:ale_sh_shellcheck_options = '--foobar'
|
||||||
|
let b:ale_sh_shellcheck_exclusions = 'foo,bar'
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ 'shellcheck --foobar -e foo,bar -f gcc -',
|
||||||
|
\ ale_linters#sh#shellcheck#GetCommand(bufnr(''))
|
||||||
|
|
||||||
|
Execute(The shellcheck command should include the dialect):
|
||||||
|
let b:is_bash = 1
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ 'shellcheck -s bash -f gcc -',
|
||||||
|
\ ale_linters#sh#shellcheck#GetCommand(bufnr(''))
|
|
@ -67,7 +67,7 @@ Execute(.js files should be executed with node on Windows):
|
||||||
\ ale_linters#javascript#standard#GetExecutable(bufnr(''))
|
\ ale_linters#javascript#standard#GetExecutable(bufnr(''))
|
||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ 'node ' . ale#Escape(b:executable) . ' --stdin %s',
|
\ ale#Escape('node.exe') . ' ' . ale#Escape(b:executable) . ' --stdin %s',
|
||||||
\ ale_linters#javascript#standard#GetCommand(bufnr(''))
|
\ ale_linters#javascript#standard#GetCommand(bufnr(''))
|
||||||
|
|
||||||
Execute(The global executable should be used otherwise):
|
Execute(The global executable should be used otherwise):
|
||||||
|
|
0
test/eslint-test-files/package.json
Normal file
0
test/eslint-test-files/package.json
Normal file
|
@ -13,22 +13,45 @@ Execute(The path to eslint.js should be run on Unix):
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\ 'command':
|
\ 'command':
|
||||||
\ ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
|
\ ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
|
||||||
\ . ' --config ' . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
|
\ . ' -c ' . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ },
|
\ },
|
||||||
\ ale#fixers#eslint#Fix(bufnr(''))
|
\ ale#fixers#eslint#Fix(bufnr(''))
|
||||||
|
|
||||||
Execute(The eslint fixer with eslint.js should be run with node on Windows):
|
Execute(The lower priority configuration file in a nested directory should be preferred):
|
||||||
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js')
|
call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-config/testfile.js')
|
||||||
let g:ale_has_override['win32'] = 1
|
|
||||||
|
|
||||||
" We have to execute the file with node.
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ {
|
\ {
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\ 'command': 'node '
|
\ 'command':
|
||||||
\ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
|
\ ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
|
||||||
\ . ' --config ' . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
|
\ . ' -c ' . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc'))
|
||||||
|
\ . ' --fix %t',
|
||||||
|
\ },
|
||||||
|
\ ale#fixers#eslint#Fix(bufnr(''))
|
||||||
|
|
||||||
|
Execute(package.json should be used as a last resort):
|
||||||
|
call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-package-json/testfile.js')
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ {
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\ 'command':
|
||||||
|
\ ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
|
||||||
|
\ . ' -c ' . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
|
||||||
|
\ . ' --fix %t',
|
||||||
|
\ },
|
||||||
|
\ ale#fixers#eslint#Fix(bufnr(''))
|
||||||
|
|
||||||
|
call ale#test#SetFilename('../eslint-test-files/package.json')
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ {
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\ 'command':
|
||||||
|
\ ale#Escape(simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint'))
|
||||||
|
\ . ' -c ' . ale#Escape(simplify(g:dir . '/../eslint-test-files/package.json'))
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ },
|
\ },
|
||||||
\ ale#fixers#eslint#Fix(bufnr(''))
|
\ ale#fixers#eslint#Fix(bufnr(''))
|
||||||
|
|
|
@ -25,7 +25,7 @@ Execute(The standard fixer with standard.js should be run with node on Windows):
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ {
|
\ {
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\ 'command': 'node '
|
\ 'command': ale#Escape('node.exe') . ' '
|
||||||
\ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/standard/bin/cmd.js'))
|
\ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/standard/bin/cmd.js'))
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ },
|
\ },
|
||||||
|
|
|
@ -25,7 +25,7 @@ Execute(The stylelint fixer with stylelint.js should be run with node on Windows
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ {
|
\ {
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\ 'command': 'node '
|
\ 'command': ale#Escape('node.exe') . ' '
|
||||||
\ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js'))
|
\ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js'))
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ },
|
\ },
|
||||||
|
|
|
@ -3,6 +3,7 @@ Before:
|
||||||
|
|
||||||
After:
|
After:
|
||||||
unlet! b:data
|
unlet! b:data
|
||||||
|
unlet! b:conn
|
||||||
|
|
||||||
Execute(GetNextMessageID() should increment appropriately):
|
Execute(GetNextMessageID() should increment appropriately):
|
||||||
" We should get the initial ID, and increment a bit.
|
" We should get the initial ID, and increment a bit.
|
||||||
|
@ -220,3 +221,51 @@ Execute(ale#lsp#ReadMessageData() should handle a message with part of a second
|
||||||
\ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}'
|
\ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}'
|
||||||
\ . b:data
|
\ . b:data
|
||||||
\ )
|
\ )
|
||||||
|
|
||||||
|
Execute(Projects with regular project roots should be registered correctly):
|
||||||
|
let b:conn = {'projects': {}}
|
||||||
|
|
||||||
|
call ale#lsp#RegisterProject(b:conn, '/foo/bar')
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ {
|
||||||
|
\ 'projects': {
|
||||||
|
\ '/foo/bar': {'initialized': 0, 'message_queue': [], 'init_request_id': 0},
|
||||||
|
\ },
|
||||||
|
\ },
|
||||||
|
\ b:conn
|
||||||
|
|
||||||
|
Execute(Projects with regular project roots should be fetched correctly):
|
||||||
|
let b:conn = {
|
||||||
|
\ 'projects': {
|
||||||
|
\ '/foo/bar': {'initialized': 0, 'message_queue': [], 'init_request_id': 0},
|
||||||
|
\ },
|
||||||
|
\}
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ {'initialized': 0, 'message_queue': [], 'init_request_id': 0},
|
||||||
|
\ ale#lsp#GetProject(b:conn, '/foo/bar')
|
||||||
|
|
||||||
|
Execute(Projects with empty project roots should be registered correctly):
|
||||||
|
let b:conn = {'projects': {}}
|
||||||
|
|
||||||
|
call ale#lsp#RegisterProject(b:conn, '')
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ {
|
||||||
|
\ 'projects': {
|
||||||
|
\ '<<EMPTY>>': {'initialized': 1, 'message_queue': [], 'init_request_id': 0},
|
||||||
|
\ },
|
||||||
|
\ },
|
||||||
|
\ b:conn
|
||||||
|
|
||||||
|
Execute(Projects with empty project roots should be fetched correctly):
|
||||||
|
let b:conn = {
|
||||||
|
\ 'projects': {
|
||||||
|
\ '<<EMPTY>>': {'initialized': 1, 'message_queue': [], 'init_request_id': 0},
|
||||||
|
\ },
|
||||||
|
\}
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ {'initialized': 1, 'message_queue': [], 'init_request_id': 0},
|
||||||
|
\ ale#lsp#GetProject(b:conn, '')
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
Before:
|
Before:
|
||||||
|
Save g:ale_change_sign_column_color
|
||||||
|
|
||||||
function! ParseHighlight(name) abort
|
function! ParseHighlight(name) abort
|
||||||
redir => l:output
|
redir => l:output
|
||||||
silent execute 'highlight ' . a:name
|
silent execute 'highlight ' . a:name
|
||||||
|
@ -20,14 +22,34 @@ Before:
|
||||||
let g:sign_highlight = ParseHighlight('SignColumn')
|
let g:sign_highlight = ParseHighlight('SignColumn')
|
||||||
|
|
||||||
After:
|
After:
|
||||||
|
Restore
|
||||||
|
|
||||||
delfunction ParseHighlight
|
delfunction ParseHighlight
|
||||||
call SetHighlight('SignColumn', g:sign_highlight)
|
call SetHighlight('SignColumn', g:sign_highlight)
|
||||||
delfunction SetHighlight
|
delfunction SetHighlight
|
||||||
unlet! g:sign_highlight
|
unlet! g:sign_highlight
|
||||||
|
|
||||||
|
sign unplace *
|
||||||
|
|
||||||
|
Execute(The SignColumn highlight shouldn't be changed if the option is off):
|
||||||
|
let g:ale_change_sign_column_color = 0
|
||||||
|
let b:sign_highlight = ParseHighlight('SignColumn')
|
||||||
|
|
||||||
|
call ale#sign#SetSigns(bufnr(''), [
|
||||||
|
\ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'W', 'text': 'x'},
|
||||||
|
\])
|
||||||
|
AssertEqual b:sign_highlight, ParseHighlight('SignColumn')
|
||||||
|
|
||||||
|
call ale#sign#SetSigns(bufnr(''), [])
|
||||||
|
AssertEqual b:sign_highlight, ParseHighlight('SignColumn')
|
||||||
|
|
||||||
Execute(The SignColumn highlight should be set and reset):
|
Execute(The SignColumn highlight should be set and reset):
|
||||||
call ale#sign#SetSignColumnHighlight(1)
|
let g:ale_change_sign_column_color = 1
|
||||||
|
|
||||||
|
call ale#sign#SetSigns(bufnr(''), [
|
||||||
|
\ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'W', 'text': 'x'},
|
||||||
|
\])
|
||||||
AssertEqual 'links to ALESignColumnWithErrors', ParseHighlight('SignColumn')
|
AssertEqual 'links to ALESignColumnWithErrors', ParseHighlight('SignColumn')
|
||||||
|
|
||||||
call ale#sign#SetSignColumnHighlight(0)
|
call ale#sign#SetSigns(bufnr(''), [])
|
||||||
AssertEqual 'links to ALESignColumnWithoutErrors', ParseHighlight('SignColumn')
|
AssertEqual 'links to ALESignColumnWithoutErrors', ParseHighlight('SignColumn')
|
||||||
|
|
|
@ -266,3 +266,14 @@ Execute(It should be possible to clear signs with empty lists):
|
||||||
|
|
||||||
Execute(No exceptions should be thrown when setting signs for invalid buffers):
|
Execute(No exceptions should be thrown when setting signs for invalid buffers):
|
||||||
call ale#sign#SetSigns(123456789, [{'lnum': 15, 'col': 2, 'type': 'W', 'text': 'e'}])
|
call ale#sign#SetSigns(123456789, [{'lnum': 15, 'col': 2, 'type': 'W', 'text': 'e'}])
|
||||||
|
|
||||||
|
Execute(Signs should be removed when lines have multiple sign IDs on them):
|
||||||
|
" We can fail to remove signs if there are multiple signs on one line,
|
||||||
|
" say after deleting lines in Vim, etc.
|
||||||
|
exec 'sign place 1000347 line=3 name=ALEErrorSign buffer=' . bufnr('')
|
||||||
|
exec 'sign place 1000348 line=3 name=ALEWarningSign buffer=' . bufnr('')
|
||||||
|
exec 'sign place 1000349 line=10 name=ALEErrorSign buffer=' . bufnr('')
|
||||||
|
exec 'sign place 1000350 line=10 name=ALEWarningSign buffer=' . bufnr('')
|
||||||
|
|
||||||
|
call ale#sign#SetSigns(bufnr(''), [])
|
||||||
|
AssertEqual [], ParseSigns()
|
||||||
|
|
|
@ -58,7 +58,7 @@ Execute(eslint.js executables should be run with node on Windows):
|
||||||
|
|
||||||
" We have to execute the file with node.
|
" We have to execute the file with node.
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ 'node '''
|
\ ale#Escape('node.exe') . ' '
|
||||||
\ . g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'
|
\ . ale#Escape(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')
|
||||||
\ . ''' -f unix --stdin --stdin-filename %s',
|
\ . ' -f unix --stdin --stdin-filename %s',
|
||||||
\ ale#handlers#eslint#GetCommand(bufnr(''))
|
\ ale#handlers#eslint#GetCommand(bufnr(''))
|
||||||
|
|
|
@ -6,12 +6,14 @@ Before:
|
||||||
Save g:ale_keep_list_window_open
|
Save g:ale_keep_list_window_open
|
||||||
Save g:ale_list_window_size
|
Save g:ale_list_window_size
|
||||||
Save g:ale_buffer_info
|
Save g:ale_buffer_info
|
||||||
|
Save g:ale_set_lists_synchronously
|
||||||
|
|
||||||
let g:ale_set_loclist = 1
|
let g:ale_set_loclist = 1
|
||||||
let g:ale_set_quickfix = 0
|
let g:ale_set_quickfix = 0
|
||||||
let g:ale_open_list = 0
|
let g:ale_open_list = 0
|
||||||
let g:ale_keep_list_window_open = 0
|
let g:ale_keep_list_window_open = 0
|
||||||
let g:ale_list_window_size = 10
|
let g:ale_list_window_size = 10
|
||||||
|
let g:ale_set_lists_synchronously = 1
|
||||||
|
|
||||||
let g:loclist = [
|
let g:loclist = [
|
||||||
\ {'bufnr': bufnr(''), 'lnum': 5, 'col': 5, 'text': 'x'},
|
\ {'bufnr': bufnr(''), 'lnum': 5, 'col': 5, 'text': 'x'},
|
||||||
|
@ -70,17 +72,14 @@ Execute(The quickfix window should open for just the loclist):
|
||||||
|
|
||||||
" It should not open for an empty list.
|
" It should not open for an empty list.
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert !ale#list#IsQuickfixOpen()
|
Assert !ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
" With a non-empty loclist, the window must open.
|
" With a non-empty loclist, the window must open.
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert ale#list#IsQuickfixOpen()
|
Assert ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
" Clear the list and it should close again.
|
" Clear the list and it should close again.
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert !ale#list#IsQuickfixOpen()
|
Assert !ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
Execute(The quickfix window height should be correct for the loclist):
|
Execute(The quickfix window height should be correct for the loclist):
|
||||||
|
@ -88,7 +87,6 @@ Execute(The quickfix window height should be correct for the loclist):
|
||||||
let g:ale_list_window_size = 7
|
let g:ale_list_window_size = 7
|
||||||
|
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
|
|
||||||
AssertEqual 7, GetQuickfixHeight()
|
AssertEqual 7, GetQuickfixHeight()
|
||||||
|
|
||||||
|
@ -97,7 +95,6 @@ Execute(The quickfix window height should be correct for the loclist with buffer
|
||||||
let b:ale_list_window_size = 8
|
let b:ale_list_window_size = 8
|
||||||
|
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
|
|
||||||
AssertEqual 8, GetQuickfixHeight()
|
AssertEqual 8, GetQuickfixHeight()
|
||||||
|
|
||||||
|
@ -107,16 +104,13 @@ Execute(The quickfix window should stay open for just the loclist):
|
||||||
|
|
||||||
" The window should stay open after even after it is made blank again.
|
" The window should stay open after even after it is made blank again.
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert ale#list#IsQuickfixOpen()
|
Assert ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
Execute(The quickfix window should not open by default when quickfix is on):
|
Execute(The quickfix window should not open by default when quickfix is on):
|
||||||
let g:ale_set_quickfix = 1
|
let g:ale_set_quickfix = 1
|
||||||
|
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert !ale#list#IsQuickfixOpen()
|
Assert !ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
Execute(The quickfix window should open for the quickfix list):
|
Execute(The quickfix window should open for the quickfix list):
|
||||||
|
@ -129,24 +123,20 @@ Execute(The quickfix window should open for the quickfix list):
|
||||||
|
|
||||||
" It should not open for an empty list.
|
" It should not open for an empty list.
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was opened when the list was empty'
|
Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was opened when the list was empty'
|
||||||
|
|
||||||
" With a non-empty quickfix list, the window must open.
|
" With a non-empty quickfix list, the window must open.
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert ale#list#IsQuickfixOpen(), 'The quickfix window was closed when the list was not empty'
|
Assert ale#list#IsQuickfixOpen(), 'The quickfix window was closed when the list was not empty'
|
||||||
|
|
||||||
" Clear this List. The window should stay open, as there are other items.
|
" Clear this List. The window should stay open, as there are other items.
|
||||||
let g:ale_buffer_info[bufnr('')].loclist = []
|
let g:ale_buffer_info[bufnr('')].loclist = []
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert ale#list#IsQuickfixOpen(), 'The quickfix window closed even though there are items in another buffer'
|
Assert ale#list#IsQuickfixOpen(), 'The quickfix window closed even though there are items in another buffer'
|
||||||
|
|
||||||
" Clear the other List now. Now the window should close.
|
" Clear the other List now. Now the window should close.
|
||||||
call remove(g:ale_buffer_info, bufnr('') + 1)
|
call remove(g:ale_buffer_info, bufnr('') + 1)
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was not closed'
|
Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was not closed'
|
||||||
|
|
||||||
Execute(The quickfix window should stay open for the quickfix list):
|
Execute(The quickfix window should stay open for the quickfix list):
|
||||||
|
@ -156,9 +146,7 @@ Execute(The quickfix window should stay open for the quickfix list):
|
||||||
|
|
||||||
" The window should stay open after even after it is made blank again.
|
" The window should stay open after even after it is made blank again.
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
Assert ale#list#IsQuickfixOpen()
|
Assert ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
Execute(The quickfix window height should be correct for the quickfix list):
|
Execute(The quickfix window height should be correct for the quickfix list):
|
||||||
|
@ -167,7 +155,6 @@ Execute(The quickfix window height should be correct for the quickfix list):
|
||||||
let g:ale_list_window_size = 7
|
let g:ale_list_window_size = 7
|
||||||
|
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
|
|
||||||
AssertEqual 7, GetQuickfixHeight()
|
AssertEqual 7, GetQuickfixHeight()
|
||||||
|
|
||||||
|
@ -177,7 +164,6 @@ Execute(The quickfix window height should be correct for the quickfix list with
|
||||||
let b:ale_list_window_size = 8
|
let b:ale_list_window_size = 8
|
||||||
|
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
|
|
||||||
AssertEqual 8, GetQuickfixHeight()
|
AssertEqual 8, GetQuickfixHeight()
|
||||||
|
|
||||||
|
@ -192,9 +178,7 @@ Execute(The buffer ale_keep_list_window_open option should be respected):
|
||||||
let b:ale_keep_list_window_open = 1
|
let b:ale_keep_list_window_open = 1
|
||||||
|
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
call ale#list#SetLists(bufnr('%'), [])
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
|
|
||||||
Assert ale#list#IsQuickfixOpen()
|
Assert ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
|
@ -205,12 +189,19 @@ Execute(The ale_open_list='on_save' option should work):
|
||||||
" The list shouldn't open yet, the event wasn't fired.
|
" The list shouldn't open yet, the event wasn't fired.
|
||||||
Assert !ale#list#IsQuickfixOpen()
|
Assert !ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
|
" Turn this option off, to ensure that we update lists immediately when we
|
||||||
|
" save buffers.
|
||||||
|
let g:ale_set_lists_synchronously = 0
|
||||||
let b:ale_save_event_fired = 1
|
let b:ale_save_event_fired = 1
|
||||||
|
|
||||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||||
" Now the list should have opened.
|
" Now the list should have opened.
|
||||||
Assert ale#list#IsQuickfixOpen()
|
Assert ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
|
call ale#list#SetLists(bufnr('%'), [])
|
||||||
|
" The window should close again when the loclist is empty.
|
||||||
|
Assert !ale#list#IsQuickfixOpen()
|
||||||
|
|
||||||
Execute(The window shouldn't open on save when ale_open_list=0):
|
Execute(The window shouldn't open on save when ale_open_list=0):
|
||||||
let b:ale_open_list = 0
|
let b:ale_open_list = 0
|
||||||
let b:ale_save_event_fired = 1
|
let b:ale_save_event_fired = 1
|
||||||
|
|
|
@ -27,12 +27,3 @@ Execute(The SetLists function should work when run in a timer):
|
||||||
\ 'type': 'E',
|
\ 'type': 'E',
|
||||||
\ 'pattern': '',
|
\ 'pattern': '',
|
||||||
\}], getloclist(0)
|
\}], getloclist(0)
|
||||||
|
|
||||||
Execute(The CloseWindowIfNeeded function should work when run in a timer):
|
|
||||||
let g:ale_open_list = 1
|
|
||||||
lopen
|
|
||||||
|
|
||||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
|
||||||
sleep 1ms
|
|
||||||
|
|
||||||
Assert !ale#list#IsQuickfixOpen(), 'The window was not closed!'
|
|
||||||
|
|
83
test/test_shell_detection.vader
Normal file
83
test/test_shell_detection.vader
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
Before:
|
||||||
|
runtime ale_linters/sh/shell.vim
|
||||||
|
runtime ale_linters/sh/shellcheck.vim
|
||||||
|
|
||||||
|
After:
|
||||||
|
call ale#linter#Reset()
|
||||||
|
|
||||||
|
unlet! b:is_bash
|
||||||
|
unlet! b:is_sh
|
||||||
|
unlet! b:is_kornshell
|
||||||
|
|
||||||
|
Given(A file with a Bash hashbang):
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
Execute(/bin/bash should be detected appropriately):
|
||||||
|
AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr(''))
|
||||||
|
AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr(''))
|
||||||
|
AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Given(A file with /bin/sh):
|
||||||
|
#!/usr/bin/env sh -eu --foobar
|
||||||
|
|
||||||
|
Execute(/bin/sh should be detected appropriately):
|
||||||
|
AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr(''))
|
||||||
|
AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr(''))
|
||||||
|
AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Given(A file with bash as an argument to env):
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
Execute(/usr/bin/env bash should be detected appropriately):
|
||||||
|
AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr(''))
|
||||||
|
AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr(''))
|
||||||
|
AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Given(A file with a tcsh hash bang and arguments):
|
||||||
|
#!/usr/bin/env tcsh -eu --foobar
|
||||||
|
|
||||||
|
Execute(tcsh should be detected appropriately):
|
||||||
|
AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr(''))
|
||||||
|
AssertEqual 'tcsh', ale_linters#sh#shell#GetExecutable(bufnr(''))
|
||||||
|
AssertEqual 'tcsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Given(A file with a zsh hash bang and arguments):
|
||||||
|
#!/usr/bin/env zsh -eu --foobar
|
||||||
|
|
||||||
|
Execute(zsh should be detected appropriately):
|
||||||
|
AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr(''))
|
||||||
|
AssertEqual 'zsh', ale_linters#sh#shell#GetExecutable(bufnr(''))
|
||||||
|
AssertEqual 'zsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Given(A file with a csh hash bang and arguments):
|
||||||
|
#!/usr/bin/env csh -eu --foobar
|
||||||
|
|
||||||
|
Execute(zsh should be detected appropriately):
|
||||||
|
AssertEqual 'csh', ale#handlers#sh#GetShellType(bufnr(''))
|
||||||
|
AssertEqual 'csh', ale_linters#sh#shell#GetExecutable(bufnr(''))
|
||||||
|
AssertEqual 'csh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Given(A file with a sh hash bang and arguments):
|
||||||
|
#!/usr/bin/env sh -eu --foobar
|
||||||
|
|
||||||
|
Execute(sh should be detected appropriately):
|
||||||
|
AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr(''))
|
||||||
|
AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr(''))
|
||||||
|
AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Given(A file without a hashbang):
|
||||||
|
|
||||||
|
Execute(The bash dialect should be used for shellcheck if b:is_bash is 1):
|
||||||
|
let b:is_bash = 1
|
||||||
|
|
||||||
|
AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Execute(The sh dialect should be used for shellcheck if b:is_sh is 1):
|
||||||
|
let b:is_sh = 1
|
||||||
|
|
||||||
|
AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
||||||
|
|
||||||
|
Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1):
|
||||||
|
let b:is_kornshell = 1
|
||||||
|
|
||||||
|
AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
|
12
test/test_should_do_nothing_conditions.vader
Normal file
12
test/test_should_do_nothing_conditions.vader
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Before:
|
||||||
|
Save &l:statusline
|
||||||
|
|
||||||
|
After:
|
||||||
|
Restore
|
||||||
|
|
||||||
|
Execute(ALE shouldn't do much of anything for ctrlp-funky buffers):
|
||||||
|
Assert !ale#ShouldDoNothing(bufnr('')), 'The preliminary check failed'
|
||||||
|
|
||||||
|
let &l:statusline = '%#CtrlPMode2# prt %*%#CtrlPMode1# line %* <mru>={%#CtrlPMode1# funky %*}=<fil> <-> %=%<%#CtrlPMode2# %{getcwd()} %*'
|
||||||
|
|
||||||
|
Assert ale#ShouldDoNothing(bufnr(''))
|
Reference in a new issue