mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-06 20:54:26 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8dcdc984b | ||
|
|
c6d3d646ac | ||
|
|
c8de2d9766 | ||
|
|
6d50074984 | ||
|
|
6b87dd24ee | ||
|
|
11fafbfd66 | ||
|
|
06c3ee61e4 | ||
|
|
5a88395bbb |
@@ -14,17 +14,9 @@ endfunction
|
||||
|
||||
function! ale_linters#javascript#standard#GetCommand(buffer) abort
|
||||
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')
|
||||
|
||||
return l:head
|
||||
return ale#node#Executable(a:buffer, l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --stdin %s'
|
||||
endfunction
|
||||
|
||||
@@ -17,18 +17,10 @@ if !exists('g:ale_sh_shell_default_shell')
|
||||
endif
|
||||
|
||||
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 len(l:banglines) == 1 && l:banglines[0] =~# '^#!'
|
||||
" 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
|
||||
if !empty(l:shell_type)
|
||||
return l:shell_type
|
||||
endif
|
||||
|
||||
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')
|
||||
endfunction
|
||||
|
||||
function! s:GetDialectArgument() abort
|
||||
if exists('b:is_bash') && b:is_bash
|
||||
return '-s bash'
|
||||
elseif exists('b:is_sh') && b:is_sh
|
||||
return '-s sh'
|
||||
elseif exists('b:is_kornshell') && b:is_kornshell
|
||||
return '-s ksh'
|
||||
function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
|
||||
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
|
||||
|
||||
if !empty(l:shell_type)
|
||||
return l:shell_type
|
||||
endif
|
||||
|
||||
" 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
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
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:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
|
||||
|
||||
return ale_linters#sh#shellcheck#GetExecutable(a:buffer)
|
||||
\ . ' ' . ale#Var(a:buffer, 'sh_shellcheck_options')
|
||||
\ . ' ' . (!empty(l:exclude_option) ? '-e ' . l:exclude_option : '')
|
||||
\ . ' ' . s:GetDialectArgument() . ' -f gcc -'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
|
||||
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
|
||||
\ . ' -f gcc -'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('sh', {
|
||||
|
||||
@@ -48,6 +48,7 @@ function! ale#ShouldDoNothing(buffer) abort
|
||||
\ || ale#util#InSandbox()
|
||||
\ || !ale#Var(a:buffer, 'enabled')
|
||||
\ || ale#FileTooLarge()
|
||||
\ || getbufvar(a:buffer, '&l:statusline') =~# 'CtrlPMode.*funky'
|
||||
endfunction
|
||||
|
||||
" (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
|
||||
call ale#list#SetLists(a:buffer, a:loclist)
|
||||
|
||||
if l:linting_is_done
|
||||
call ale#list#CloseWindowIfNeeded(a:buffer)
|
||||
endif
|
||||
endif
|
||||
|
||||
if exists('*ale#statusline#Update')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
scriptencoding utf-8
|
||||
" Author: Peter Renström <renstrom.peter@gmail.com>
|
||||
" Description: Fixing C/C++ files with clang-format.
|
||||
|
||||
|
||||
@@ -28,16 +28,8 @@ function! ale#fixers#eslint#Fix(buffer) abort
|
||||
return 0
|
||||
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 {
|
||||
\ 'command': l:head
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --config ' . ale#Escape(l:config)
|
||||
\ . ' --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
|
||||
@@ -11,16 +11,8 @@ endfunction
|
||||
function! ale#fixers#standard#Fix(buffer) abort
|
||||
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 {
|
||||
\ 'command': l:head
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
|
||||
@@ -15,16 +15,8 @@ endfunction
|
||||
function! ale#fixers#stylelint#Fix(buffer) abort
|
||||
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 {
|
||||
\ 'command': l:head
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
|
||||
@@ -17,17 +17,9 @@ endfunction
|
||||
function! ale#handlers#eslint#GetCommand(buffer) abort
|
||||
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')
|
||||
|
||||
return l:head
|
||||
return ale#node#Executable(a:buffer, l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -f unix --stdin --stdin-filename %s'
|
||||
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'],
|
||||
\ 'go': ['gofmt', 'golint', 'go vet'],
|
||||
\ 'help': [],
|
||||
\ 'python': ['flake8', 'mypy', 'pylint'],
|
||||
\ 'rust': ['cargo'],
|
||||
\ 'spec': [],
|
||||
\ 'text': [],
|
||||
|
||||
@@ -56,6 +56,10 @@ function! s:FixList(list) abort
|
||||
return l:new_list
|
||||
endfunction
|
||||
|
||||
function! s:BufWinId(buffer) abort
|
||||
return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
|
||||
endfunction
|
||||
|
||||
function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
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.
|
||||
" We'll set result in the current window, which might not be correct,
|
||||
" 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')
|
||||
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
|
||||
|
||||
let l:keep_open = ale#Var(a:buffer, 'keep_list_window_open')
|
||||
|
||||
" 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
|
||||
" 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:mode = mode()
|
||||
let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\<c-v>"
|
||||
@@ -117,10 +119,23 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
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
|
||||
|
||||
function! ale#list#SetLists(buffer, loclist) abort
|
||||
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)
|
||||
else
|
||||
call ale#util#StartPartialTimer(
|
||||
@@ -131,7 +146,7 @@ function! ale#list#SetLists(buffer, loclist) abort
|
||||
endif
|
||||
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)
|
||||
return
|
||||
endif
|
||||
@@ -143,22 +158,14 @@ function! s:CloseWindowIfNeededImpl(timer_id, buffer) abort
|
||||
if empty(getqflist())
|
||||
cclose
|
||||
endif
|
||||
elseif g:ale_set_loclist && empty(getloclist(0))
|
||||
lclose
|
||||
else
|
||||
let l:win_id = s:BufWinId(a:buffer)
|
||||
|
||||
if g:ale_set_loclist && empty(getloclist(l:win_id))
|
||||
lclose
|
||||
endif
|
||||
endif
|
||||
" Ignore 'Cannot close last window' errors.
|
||||
catch /E444/
|
||||
endtry
|
||||
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)
|
||||
endfunction
|
||||
|
||||
function! s:RegisterProject(conn, project_root) abort
|
||||
if !has_key(a:conn.projects, a:project_root)
|
||||
function! ale#lsp#RegisterProject(conn, project_root) abort
|
||||
" 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.
|
||||
let a:conn.projects[a:project_root] = {
|
||||
let a:conn.projects[l:key] = {
|
||||
\ 'initialized': empty(a:project_root),
|
||||
\ 'init_request_id': 0,
|
||||
\ 'message_queue': [],
|
||||
@@ -253,6 +257,12 @@ function! s:RegisterProject(conn, project_root) abort
|
||||
endif
|
||||
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.
|
||||
"
|
||||
" 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
|
||||
" Add the callback to the List if it's not there already.
|
||||
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
|
||||
endfunction
|
||||
@@ -311,7 +321,7 @@ function! ale#lsp#ConnectToAddress(address, project_root, callback) abort
|
||||
let l:conn.id = a:address
|
||||
" Add the callback to the List if it's not there already.
|
||||
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
|
||||
endfunction
|
||||
@@ -344,7 +354,7 @@ function! ale#lsp#Send(conn_id, message, ...) abort
|
||||
return 0
|
||||
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)
|
||||
return 0
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" 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
|
||||
" 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')
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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*
|
||||
|
||||
|
||||
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(''))
|
||||
|
||||
AssertEqual
|
||||
\ 'node ' . ale#Escape(b:executable) . ' --stdin %s',
|
||||
\ ale#Escape('node.exe') . ' ' . ale#Escape(b:executable) . ' --stdin %s',
|
||||
\ ale_linters#javascript#standard#GetCommand(bufnr(''))
|
||||
|
||||
Execute(The global executable should be used otherwise):
|
||||
|
||||
@@ -26,7 +26,7 @@ Execute(The eslint fixer with eslint.js should be run with node on Windows):
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'command': 'node '
|
||||
\ 'command': ale#Escape('node.exe') . ' '
|
||||
\ . 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'))
|
||||
\ . ' --fix %t',
|
||||
|
||||
@@ -25,7 +25,7 @@ Execute(The standard fixer with standard.js should be run with node on Windows):
|
||||
AssertEqual
|
||||
\ {
|
||||
\ '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'))
|
||||
\ . ' --fix %t',
|
||||
\ },
|
||||
|
||||
@@ -25,7 +25,7 @@ Execute(The stylelint fixer with stylelint.js should be run with node on Windows
|
||||
AssertEqual
|
||||
\ {
|
||||
\ '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'))
|
||||
\ . ' --fix %t',
|
||||
\ },
|
||||
|
||||
@@ -3,6 +3,7 @@ Before:
|
||||
|
||||
After:
|
||||
unlet! b:data
|
||||
unlet! b:conn
|
||||
|
||||
Execute(GetNextMessageID() should increment appropriately):
|
||||
" 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Ü"}}'
|
||||
\ . 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, '')
|
||||
|
||||
@@ -58,7 +58,7 @@ Execute(eslint.js executables should be run with node on Windows):
|
||||
|
||||
" We have to execute the file with node.
|
||||
AssertEqual
|
||||
\ 'node '''
|
||||
\ . g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'
|
||||
\ . ''' -f unix --stdin --stdin-filename %s',
|
||||
\ ale#Escape('node.exe') . ' '
|
||||
\ . ale#Escape(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')
|
||||
\ . ' -f unix --stdin --stdin-filename %s',
|
||||
\ ale#handlers#eslint#GetCommand(bufnr(''))
|
||||
|
||||
@@ -6,12 +6,14 @@ Before:
|
||||
Save g:ale_keep_list_window_open
|
||||
Save g:ale_list_window_size
|
||||
Save g:ale_buffer_info
|
||||
Save g:ale_set_lists_synchronously
|
||||
|
||||
let g:ale_set_loclist = 1
|
||||
let g:ale_set_quickfix = 0
|
||||
let g:ale_open_list = 0
|
||||
let g:ale_keep_list_window_open = 0
|
||||
let g:ale_list_window_size = 10
|
||||
let g:ale_set_lists_synchronously = 1
|
||||
|
||||
let g:loclist = [
|
||||
\ {'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.
|
||||
call ale#list#SetLists(bufnr('%'), [])
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert !ale#list#IsQuickfixOpen()
|
||||
|
||||
" With a non-empty loclist, the window must open.
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert ale#list#IsQuickfixOpen()
|
||||
|
||||
" Clear the list and it should close again.
|
||||
call ale#list#SetLists(bufnr('%'), [])
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert !ale#list#IsQuickfixOpen()
|
||||
|
||||
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
|
||||
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
|
||||
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
|
||||
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
|
||||
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.
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
call ale#list#SetLists(bufnr('%'), [])
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert ale#list#IsQuickfixOpen()
|
||||
|
||||
Execute(The quickfix window should not open by default when quickfix is on):
|
||||
let g:ale_set_quickfix = 1
|
||||
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert !ale#list#IsQuickfixOpen()
|
||||
|
||||
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.
|
||||
call ale#list#SetLists(bufnr('%'), [])
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was opened when the list was empty'
|
||||
|
||||
" With a non-empty quickfix list, the window must open.
|
||||
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'
|
||||
|
||||
" Clear this List. The window should stay open, as there are other items.
|
||||
let g:ale_buffer_info[bufnr('')].loclist = []
|
||||
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'
|
||||
|
||||
" Clear the other List now. Now the window should close.
|
||||
call remove(g:ale_buffer_info, bufnr('') + 1)
|
||||
call ale#list#SetLists(bufnr('%'), [])
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was not closed'
|
||||
|
||||
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.
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
call ale#list#SetLists(bufnr('%'), [])
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
Assert ale#list#IsQuickfixOpen()
|
||||
|
||||
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
|
||||
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
|
||||
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
|
||||
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
|
||||
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
|
||||
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
call ale#list#SetLists(bufnr('%'), [])
|
||||
call ale#list#CloseWindowIfNeeded(bufnr(''))
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
call ale#list#SetLists(bufnr('%'), g:loclist)
|
||||
" Now the list should have opened.
|
||||
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):
|
||||
let b:ale_open_list = 0
|
||||
let b:ale_save_event_fired = 1
|
||||
|
||||
@@ -27,12 +27,3 @@ Execute(The SetLists function should work when run in a timer):
|
||||
\ 'type': 'E',
|
||||
\ 'pattern': '',
|
||||
\}], 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 New Issue
Block a user