summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml5
-rw-r--r--.travis.yml4
-rw-r--r--ale_linters/python/mypy.vim1
-rw-r--r--ale_linters/sh/shell.vim4
-rw-r--r--autoload/ale/c.vim131
-rw-r--r--autoload/ale/completion.vim28
-rw-r--r--autoload/ale/debugging.vim1
-rw-r--r--autoload/ale/fix/registry.vim15
-rw-r--r--autoload/ale/fixers/black.vim4
-rw-r--r--autoload/ale/fixers/dfmt.vim18
-rw-r--r--autoload/ale/fixers/gnatpp.vim17
-rw-r--r--autoload/ale/fixers/hindent.vim20
-rw-r--r--autoload/ale/handlers/languagetool.vim5
-rw-r--r--autoload/ale/highlight.vim71
-rw-r--r--autoload/ale/list.vim37
-rw-r--r--autoload/ale/sign.vim3
-rw-r--r--autoload/asyncomplete/sources/ale.vim26
-rw-r--r--doc/ale-ada.txt11
-rw-r--r--doc/ale-d.txt9
-rw-r--r--doc/ale-haskell.txt22
-rw-r--r--doc/ale-supported-languages-and-tools.txt3
-rw-r--r--doc/ale.txt39
-rw-r--r--supported-tools.md7
-rw-r--r--test/ada_files/testfile.adb0
-rw-r--r--test/command_callback/python_paths/with_virtualenv/subdir/foo/bar.pyi0
-rw-r--r--test/command_callback/test_languagetool_command_callback.vader9
-rw-r--r--test/completion/test_completion_events.vader28
-rw-r--r--test/d_files/test.d0
-rw-r--r--test/fixers/test_black_fixer_callback.vader8
-rw-r--r--test/fixers/test_dfmt_fixer_callback.vader40
-rw-r--r--test/fixers/test_gnatpp_fixer_callback.vader28
-rw-r--r--test/fixers/test_hindent_fixer_callback.vader18
-rw-r--r--test/handler/test_shell_handler.vader135
-rwxr-xr-xtest/script/check-toc2
-rw-r--r--test/test_ale_info.vader3
-rw-r--r--test/test_ale_toggle.vader84
-rw-r--r--test/test_c_flag_parsing.vader162
-rw-r--r--test/test_highlight_placement.vader246
38 files changed, 1046 insertions, 198 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 54113953..aca83191 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -5,6 +5,11 @@ clone_depth: 10
# Use the directory C:\testplugin so test directories will mostly work.
clone_folder: C:\testplugin
+branches:
+ only:
+ - master
+ - /v\d+\.\d+\.(x|\d+)/
+
# Cache the vim and vader directories between builds.
cache:
- C:\vim -> .appveyor.yml
diff --git a/.travis.yml b/.travis.yml
index d48c1e08..00baff1c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,10 @@ sudo: required
services:
- docker
language: generic
+branches:
+ only:
+ - master
+ - /^v\d+\.\d+\.(x|\d+)$/
env:
- OPTIONS=--vim-80-only
- OPTIONS=--vim-81-only
diff --git a/ale_linters/python/mypy.vim b/ale_linters/python/mypy.vim
index c4c6507f..dc4044e6 100644
--- a/ale_linters/python/mypy.vim
+++ b/ale_linters/python/mypy.vim
@@ -78,4 +78,5 @@ call ale#linter#Define('python', {
\ 'executable': function('ale_linters#python#mypy#GetExecutable'),
\ 'command': function('ale_linters#python#mypy#GetCommand'),
\ 'callback': 'ale_linters#python#mypy#Handle',
+\ 'output_stream': 'both'
\})
diff --git a/ale_linters/sh/shell.vim b/ale_linters/sh/shell.vim
index 189dc21d..171fe64e 100644
--- a/ale_linters/sh/shell.vim
+++ b/ale_linters/sh/shell.vim
@@ -34,8 +34,10 @@ function! ale_linters#sh#shell#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" bash: line 13: syntax error near unexpected token `d'
+ " bash:行0: 未预期的符号“done”附近有语法错误
+ " bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符
" sh: 11: Syntax error: "(" unexpected
- let l:pattern = '\v(line |: ?)(\d+): (.+)$'
+ let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim
index 2d2083da..5540ec14 100644
--- a/autoload/ale/c.vim
+++ b/autoload/ale/c.vim
@@ -28,76 +28,107 @@ function! ale#c#GetBuildDirectory(buffer) abort
return ale#path#Dirname(l:json_file)
endfunction
-function! ale#c#AreSpecialCharsBalanced(option) abort
- " Escape \"
- let l:option_escaped = substitute(a:option, '\\"', '', 'g')
-
- " Retain special chars only
- let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g')
- let l:special_chars = split(l:special_chars, '\zs')
-
- " Check if they are balanced
+function! ale#c#ShellSplit(line) abort
let l:stack = []
+ let l:args = ['']
+ let l:prev = ''
- for l:char in l:special_chars
- if l:char is# ')'
- if len(l:stack) == 0 || get(l:stack, -1) isnot# '('
- return 0
+ for l:char in split(a:line, '\zs')
+ if l:char is# ''''
+ if len(l:stack) > 0 && get(l:stack, -1) is# ''''
+ call remove(l:stack, -1)
+ elseif (len(l:stack) == 0 || get(l:stack, -1) isnot# '"') && l:prev isnot# '\'
+ call add(l:stack, l:char)
endif
-
- call remove(l:stack, -1)
- elseif l:char is# '('
- call add(l:stack, l:char)
- else
+ elseif (l:char is# '"' || l:char is# '`') && l:prev isnot# '\'
if len(l:stack) > 0 && get(l:stack, -1) is# l:char
call remove(l:stack, -1)
- else
+ elseif len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
call add(l:stack, l:char)
endif
+ elseif (l:char is# '(' || l:char is# '[' || l:char is# '{') && l:prev isnot# '\'
+ if len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
+ call add(l:stack, l:char)
+ endif
+ elseif (l:char is# ')' || l:char is# ']' || l:char is# '}') && l:prev isnot# '\'
+ if len(l:stack) > 0 && get(l:stack, -1) is# {')': '(', ']': '[', '}': '{'}[l:char]
+ call remove(l:stack, -1)
+ endif
+ elseif l:char is# ' ' && len(l:stack) == 0
+ if len(get(l:args, -1)) > 0
+ call add(l:args, '')
+ endif
+
+ continue
endif
+
+ let l:args[-1] = get(l:args, -1) . l:char
endfor
- return len(l:stack) == 0
+ return l:args
endfunction
function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
- let l:split_lines = split(a:cflag_line)
+ let l:cflags_list = []
+
+ let l:split_lines = ale#c#ShellSplit(a:cflag_line)
let l:option_index = 0
while l:option_index < len(l:split_lines)
- let l:next_option_index = l:option_index + 1
-
- " Join space-separated option
- while l:next_option_index < len(l:split_lines)
- \&& stridx(l:split_lines[l:next_option_index], '-') != 0
- let l:next_option_index += 1
- endwhile
-
- let l:option = join(l:split_lines[l:option_index : l:next_option_index-1], ' ')
- call remove(l:split_lines, l:option_index, l:next_option_index-1)
- call insert(l:split_lines, l:option, l:option_index)
-
- " Ignore invalid or conflicting options
- if stridx(l:option, '-') != 0
- \|| stridx(l:option, '-o') == 0
- \|| stridx(l:option, '-c') == 0
- call remove(l:split_lines, l:option_index)
- let l:option_index = l:option_index - 1
- " Fix relative path
- elseif stridx(l:option, '-I') == 0
- if !(stridx(l:option, ':') == 2+1 || stridx(l:option, '/') == 2+0)
- let l:option = '-I' . a:path_prefix . s:sep . l:option[2:]
- call remove(l:split_lines, l:option_index)
- call insert(l:split_lines, l:option, l:option_index)
+ let l:option = l:split_lines[l:option_index]
+ let l:option_index = l:option_index + 1
+
+ " Include options, that may need relative path fix
+ if stridx(l:option, '-I') == 0
+ \ || stridx(l:option, '-iquote') == 0
+ \ || stridx(l:option, '-isystem') == 0
+ \ || stridx(l:option, '-idirafter') == 0
+ if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
+ let l:arg = join(split(l:option, '\zs')[2:], '')
+ let l:option = '-I'
+ else
+ let l:arg = l:split_lines[l:option_index]
+ let l:option_index = l:option_index + 1
endif
- endif
- let l:option_index = l:option_index + 1
- endwhile
+ " Fix relative paths if needed
+ if stridx(l:arg, s:sep) != 0 && stridx(l:arg, '/') != 0
+ let l:rel_path = substitute(l:arg, '"', '', 'g')
+ let l:rel_path = substitute(l:rel_path, '''', '', 'g')
+ let l:arg = ale#Escape(a:path_prefix . s:sep . l:rel_path)
+ endif
+
+ call add(l:cflags_list, l:option)
+ call add(l:cflags_list, l:arg)
+ " Options with arg that can be grouped with the option or separate
+ elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0
+ call add(l:cflags_list, l:option)
- call uniq(l:split_lines)
+ if l:option is# '-D' || l:option is# '-B'
+ call add(l:cflags_list, l:split_lines[l:option_index])
+ let l:option_index = l:option_index + 1
+ endif
+ " Options that have an argument (always separate)
+ elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0
+ \ || l:option is# '-isysroot' || l:option is# '-imultilib'
+ call add(l:cflags_list, l:option)
+ call add(l:cflags_list, l:split_lines[l:option_index])
+ let l:option_index = l:option_index + 1
+ " Options without argument
+ elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0)
+ \ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0
+ \ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0
+ \ || (stridx(l:option, '-f') == 0 && stridx(l:option, '-fdump') != 0 && stridx(l:option, '-fdiagnostics') != 0 && stridx(l:option, '-fno-show-column') != 0)
+ \ || stridx(l:option, '-O') == 0
+ \ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs'
+ \ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0
+ \ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix'
+ \ || stridx(l:option, '-m') == 0
+ call add(l:cflags_list, l:option)
+ endif
+ endwhile
- return join(l:split_lines, ' ')
+ return join(l:cflags_list, ' ')
endfunction
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim
index c0e8abd9..ebf32909 100644
--- a/autoload/ale/completion.vim
+++ b/autoload/ale/completion.vim
@@ -267,6 +267,14 @@ function! ale#completion#Show(result) abort
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
\)
endif
+
+ if l:source is# 'ale-callback'
+ call b:CompleteCallback(b:ale_completion_result)
+ endif
+endfunction
+
+function! ale#completion#GetAllTriggers() abort
+ return deepcopy(s:trigger_character_map)
endfunction
function! s:CompletionStillValid(request_id) abort
@@ -280,6 +288,7 @@ function! s:CompletionStillValid(request_id) abort
\ b:ale_completion_info.column == l:column
\ || b:ale_completion_info.source is# 'deoplete'
\ || b:ale_completion_info.source is# 'ale-omnifunc'
+ \ || b:ale_completion_info.source is# 'ale-callback'
\)
endfunction
@@ -560,12 +569,25 @@ endfunction
" This function can be used to manually trigger autocomplete, even when
" g:ale_completion_enabled is set to false
-function! ale#completion#GetCompletions(source) abort
+function! ale#completion#GetCompletions(...) abort
+ let l:source = get(a:000, 0, '')
+ let l:options = get(a:000, 1, {})
+
+ if len(a:000) > 2
+ throw 'Too many arguments!'
+ endif
+
+ let l:CompleteCallback = get(l:options, 'callback', v:null)
+
+ if l:CompleteCallback isnot v:null
+ let b:CompleteCallback = l:CompleteCallback
+ endif
+
let [l:line, l:column] = getpos('.')[1:2]
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
- if a:source is# 'ale-automatic' && empty(l:prefix)
+ if l:source is# 'ale-automatic' && empty(l:prefix)
return 0
endif
@@ -578,7 +600,7 @@ function! ale#completion#GetCompletions(source) abort
\ 'prefix': l:prefix,
\ 'conn_id': 0,
\ 'request_id': 0,
- \ 'source': a:source,
+ \ 'source': l:source,
\}
unlet! b:ale_completion_result
diff --git a/autoload/ale/debugging.vim b/autoload/ale/debugging.vim
index 379c0d73..4e134f8c 100644
--- a/autoload/ale/debugging.vim
+++ b/autoload/ale/debugging.vim
@@ -50,6 +50,7 @@ let s:global_variable_list = [
\ 'ale_sign_style_error',
\ 'ale_sign_style_warning',
\ 'ale_sign_warning',
+\ 'ale_sign_highlight_linenrs',
\ 'ale_statusline_format',
\ 'ale_type_map',
\ 'ale_use_global_executables',
diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim
index c5ef1544..d21cb227 100644
--- a/autoload/ale/fix/registry.vim
+++ b/autoload/ale/fix/registry.vim
@@ -27,6 +27,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.',
\ },
+\ 'dfmt': {
+\ 'function': 'ale#fixers#dfmt#Fix',
+\ 'suggested_filetypes': ['d'],
+\ 'description': 'Fix D files with dfmt.',
+\ },
\ 'fecs': {
\ 'function': 'ale#fixers#fecs#Fix',
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
@@ -215,6 +220,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['haskell'],
\ 'description': 'Fix Haskell files with brittany.',
\ },
+\ 'hindent': {
+\ 'function': 'ale#fixers#hindent#Fix',
+\ 'suggested_filetypes': ['haskell'],
+\ 'description': 'Fix Haskell files with hindent.',
+\ },
\ 'hlint': {
\ 'function': 'ale#fixers#hlint#Fix',
\ 'suggested_filetypes': ['haskell'],
@@ -325,6 +335,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Sort Python imports with reorder-python-imports.',
\ },
+\ 'gnatpp': {
+\ 'function': 'ale#fixers#gnatpp#Fix',
+\ 'suggested_filetypes': ['ada'],
+\ 'description': 'Format Ada files with gnatpp.',
+\ },
\}
" Reset the function registry to the default entries.
diff --git a/autoload/ale/fixers/black.vim b/autoload/ale/fixers/black.vim
index 367b8d52..fba6c3b4 100644
--- a/autoload/ale/fixers/black.vim
+++ b/autoload/ale/fixers/black.vim
@@ -29,6 +29,10 @@ function! ale#fixers#black#Fix(buffer) abort
let l:options = ale#Var(a:buffer, 'python_black_options')
+ if expand('#' . a:buffer . ':e') is? 'pyi'
+ let l:options .= '--pyi'
+ endif
+
return {
\ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '')
diff --git a/autoload/ale/fixers/dfmt.vim b/autoload/ale/fixers/dfmt.vim
new file mode 100644
index 00000000..0072e045
--- /dev/null
+++ b/autoload/ale/fixers/dfmt.vim
@@ -0,0 +1,18 @@
+" Author: theoldmoon0602
+" Description: Integration of dfmt with ALE.
+
+call ale#Set('d_dfmt_executable', 'dfmt')
+call ale#Set('d_dfmt_options', '')
+
+function! ale#fixers#dfmt#Fix(buffer) abort
+ let l:executable = ale#Var(a:buffer, 'd_dfmt_executable')
+ let l:options = ale#Var(a:buffer, 'd_dfmt_options')
+
+ return {
+ \ 'command': ale#Escape(l:executable)
+ \ . ' -i'
+ \ . (empty(l:options) ? '' : ' ' . l:options)
+ \ . ' %t',
+ \ 'read_temporary_file': 1,
+ \}
+endfunction
diff --git a/autoload/ale/fixers/gnatpp.vim b/autoload/ale/fixers/gnatpp.vim
new file mode 100644
index 00000000..bf3d484e
--- /dev/null
+++ b/autoload/ale/fixers/gnatpp.vim
@@ -0,0 +1,17 @@
+" Author: tim <tim@inept.tech>
+" Description: Fix files with gnatpp.
+
+call ale#Set('ada_gnatpp_executable', 'gnatpp')
+call ale#Set('ada_gnatpp_options', '')
+
+function! ale#fixers#gnatpp#Fix(buffer) abort
+ let l:executable = ale#Var(a:buffer, 'ada_gnatpp_executable')
+ let l:options = ale#Var(a:buffer, 'ada_gnatpp_options')
+
+ return {
+ \ 'command': ale#Escape(l:executable)
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . ' %t',
+ \ 'read_temporary_file': 1,
+ \}
+endfunction
diff --git a/autoload/ale/fixers/hindent.vim b/autoload/ale/fixers/hindent.vim
new file mode 100644
index 00000000..b6009a2c
--- /dev/null
+++ b/autoload/ale/fixers/hindent.vim
@@ -0,0 +1,20 @@
+" Author: AlexeiDrake <drake.alexei@gmail.com>
+" Description: Integration of hindent formatting with ALE.
+"
+call ale#Set('haskell_hindent_executable', 'hindent')
+
+function! ale#fixers#hindent#GetExecutable(buffer) abort
+ let l:executable = ale#Var(a:buffer, 'haskell_hindent_executable')
+
+ return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hindent')
+endfunction
+
+function! ale#fixers#hindent#Fix(buffer) abort
+ let l:executable = ale#fixers#hindent#GetExecutable(a:buffer)
+
+ return {
+ \ 'command': l:executable
+ \ . ' %t',
+ \ 'read_temporary_file': 1,
+ \}
+endfunction
diff --git a/autoload/ale/handlers/languagetool.vim b/autoload/ale/handlers/languagetool.vim
index 10e049df..73974ceb 100644
--- a/autoload/ale/handlers/languagetool.vim
+++ b/autoload/ale/handlers/languagetool.vim
@@ -2,6 +2,7 @@
" Description: languagetool for markdown files
"
call ale#Set('languagetool_executable', 'languagetool')
+call ale#Set('languagetool_options', '--autoDetect')
function! ale#handlers#languagetool#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'languagetool_executable')
@@ -9,8 +10,10 @@ endfunction
function! ale#handlers#languagetool#GetCommand(buffer) abort
let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer)
+ let l:options = ale#Var(a:buffer, 'languagetool_options')
- return ale#Escape(l:executable) . ' --autoDetect %s'
+ return ale#Escape(l:executable)
+ \ . (empty(l:options) ? '' : ' ' . l:options) . ' %s'
endfunction
function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort
diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim
index cb7911e1..82ad57e0 100644
--- a/autoload/ale/highlight.vim
+++ b/autoload/ale/highlight.vim
@@ -26,6 +26,25 @@ endif
let s:MAX_POS_VALUES = 8
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
+let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
+
+if s:has_nvim_highlight
+ let s:ns_id = nvim_create_namespace('ale_highlight')
+endif
+
+" Wrappers are necessary to test this functionality by faking the calls in tests.
+function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
+ " Ignore all errors for adding highlights.
+ try
+ call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
+ catch
+ endtry
+endfunction
+
+function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
+ call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end)
+endfunction
+
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
if a:line >= a:end_line
" For single lines, just return the one position.
@@ -51,15 +70,53 @@ endfunction
" except these which have matching loclist item entries.
function! ale#highlight#RemoveHighlights() abort
- for l:match in getmatches()
- if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
- call matchdelete(l:match.id)
- endif
- endfor
+ if s:has_nvim_highlight
+ call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
+ else
+ for l:match in getmatches()
+ if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
+ call matchdelete(l:match.id)
+ endif
+ endfor
+ endif
+endfunction
+
+" Same semantics of matchaddpos but will use nvim_buf_add_highlight if
+" available. This involves iterating over the position list, switching from
+" 1-based indexing to 0-based indexing, and translating the multiple ways
+" that position can be specified for matchaddpos into line + col_start +
+" col_end.
+function! s:matchaddpos(group, pos_list) abort
+ if s:has_nvim_highlight
+ for l:pos in a:pos_list
+ let l:line = type(l:pos) == v:t_number
+ \ ? l:pos - 1
+ \ : l:pos[0] - 1
+
+ if type(l:pos) == v:t_number || len(l:pos) == 1
+ let l:col_start = 0
+ let l:col_end = s:MAX_COL_SIZE
+ else
+ let l:col_start = l:pos[1] - 1
+ let l:col_end = l:col_start + get(l:pos, 2, 1)
+ endif
+
+ call ale#highlight#nvim_buf_add_highlight(
+ \ bufnr(''),
+ \ s:ns_id,
+ \ a:group,
+ \ l:line,
+ \ l:col_start,
+ \ l:col_end,
+ \)
+ endfor
+ else
+ call matchaddpos(a:group, a:pos_list)
+ endif
endfunction
function! s:highlight_line(bufnr, lnum, group) abort
- call matchaddpos(a:group, [a:lnum])
+ call s:matchaddpos(a:group, [a:lnum])
endfunction
function! s:highlight_range(bufnr, range, group) abort
@@ -72,7 +129,7 @@ function! s:highlight_range(bufnr, range, group) abort
\ a:range.end_lnum,
\ a:range.end_col
\ ),
- \ 'matchaddpos(a:group, v:val)'
+ \ 's:matchaddpos(a:group, v:val)'
\)
endfunction
diff --git a/autoload/ale/list.vim b/autoload/ale/list.vim
index e9f3f4ec..4bfe2a7b 100644
--- a/autoload/ale/list.vim
+++ b/autoload/ale/list.vim
@@ -103,6 +103,9 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
endfor
endif
+ " Save the current view before opening/closing any window
+ call setbufvar(a:buffer, 'ale_winview', winsaveview())
+
" 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
@@ -141,6 +144,8 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
normal! "\<c-g>"
endif
endif
+
+ call s:RestoreViewIfNeeded(a:buffer)
endif
" If ALE isn't currently checking for more problems, close the window if
@@ -151,6 +156,30 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
endif
endfunction
+" Try to restore the window view after closing any of the lists to avoid making
+" the it moving around, especially useful when on insert mode
+function! s:RestoreViewIfNeeded(buffer) abort
+ let l:saved_view = getbufvar(a:buffer, 'ale_winview', {})
+
+ " Saved view is empty, can't do anything
+ if empty(l:saved_view)
+ return
+ endif
+
+ " Check wether the cursor has moved since linting was actually requested. If
+ " the user has indeed moved lines, do nothing
+ let l:current_view = winsaveview()
+
+ if l:current_view['lnum'] != l:saved_view['lnum']
+ return
+ endif
+
+ " Anchor view by topline if the list is set to open horizontally
+ if ale#Var(a:buffer, 'list_vertical') == 0
+ call winrestview({'topline': l:saved_view['topline']})
+ 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)
@@ -174,12 +203,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
return
endif
+ let l:did_close_any_list = 0
+
try
" Only close windows if the quickfix list or loclist is completely empty,
" including errors set through other means.
if g:ale_set_quickfix
if empty(getqflist())
cclose
+ let l:did_close_any_list = 1
endif
else
let l:win_ids = s:WinFindBuf(a:buffer)
@@ -187,10 +219,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
for l:win_id in l:win_ids
if g:ale_set_loclist && empty(getloclist(l:win_id))
lclose
+ let l:did_close_any_list = 1
endif
endfor
endif
" Ignore 'Cannot close last window' errors.
catch /E444/
endtry
+
+ if l:did_close_any_list
+ call s:RestoreViewIfNeeded(a:buffer)
+ endif
endfunction
diff --git a/autoload/ale/sign.vim b/autoload/ale/sign.vim
index eb0dd1cd..829de118 100644
--- a/autoload/ale/sign.vim
+++ b/autoload/ale/sign.vim
@@ -20,6 +20,7 @@ let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
" This flag can be set to 1 to keep sign gutter always open
let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
+let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0)
if !hlexists('ALEErrorSign')
highlight link ALEErrorSign error
@@ -82,7 +83,7 @@ execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
sign define ALEDummySign
-if has('nvim-0.3.2')
+if g:ale_sign_highlight_linenrs && has('nvim-0.3.2')
if !hlexists('ALEErrorSignLineNr')
highlight link ALEErrorSignLineNr CursorLineNr
endif
diff --git a/autoload/asyncomplete/sources/ale.vim b/autoload/asyncomplete/sources/ale.vim
new file mode 100644
index 00000000..ce793773
--- /dev/null
+++ b/autoload/asyncomplete/sources/ale.vim
@@ -0,0 +1,26 @@
+function! asyncomplete#sources#ale#get_source_options(...) abort
+ let l:default = extend({
+ \ 'name': 'ale',
+ \ 'completor': function('asyncomplete#sources#ale#completor'),
+ \ 'whitelist': ['*'],
+ \ 'triggers': asyncomplete#sources#ale#get_triggers(),
+ \ }, a:0 >= 1 ? a:1 : {})
+
+ return extend(l:default, {'refresh_pattern': '\k\+$'})
+endfunction
+
+function! asyncomplete#sources#ale#get_triggers() abort
+ let l:triggers = ale#completion#GetAllTriggers()
+ let l:triggers['*'] = l:triggers['<default>']
+
+ return l:triggers
+endfunction
+
+function! asyncomplete#sources#ale#completor(options, context) abort
+ let l:keyword = matchstr(a:context.typed, '\w\+$')
+ let l:startcol = a:context.col - len(l:keyword)
+
+ call ale#completion#GetCompletions('ale-callback', { 'callback': {completions ->
+ \ asyncomplete#complete(a:options.name, a:context, l:startcol, completions)
+ \ }})
+endfunction
diff --git a/doc/ale-ada.txt b/doc/ale-ada.txt
index 93e3261a..2ac30c0a 100644
--- a/doc/ale-ada.txt
+++ b/doc/ale-ada.txt
@@ -22,4 +22,15 @@ g:ale_ada_gcc_options *g:ale_ada_gcc_options*
===============================================================================
+gnatpp *ale-ada-gnatpp*
+
+g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options*
+ *b:ale_ada_gnatpp_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be set to pass extra options to the gnatpp fixer.
+
+
+===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-d.txt b/doc/ale-d.txt
index 55596062..72349a20 100644
--- a/doc/ale-d.txt
+++ b/doc/ale-d.txt
@@ -1,6 +1,15 @@
===============================================================================
ALE D Integration *ale-d-options*
+===============================================================================
+dfmt *ale-d-dfmt*
+
+g:ale_d_dfmt_options *g:ale_d_dfmt_options*
+ *b:ale_d_dfmt_options*
+ Type: |String|
+ Default: `''`
+
+This variable can be set to pass additional options to the dfmt fixer.
===============================================================================
dls *ale-d-dls*
diff --git a/doc/ale-haskell.txt b/doc/ale-haskell.txt
index e2073e37..5dd3ec15 100644
--- a/doc/ale-haskell.txt
+++ b/doc/ale-haskell.txt
@@ -12,6 +12,7 @@ g:ale_haskell_brittany_executable *g:ale_haskell_brittany_executable*
This variable can be changed to use a different executable for brittany.
+
===============================================================================
floskell *ale-haskell-floskell*
@@ -22,6 +23,7 @@ g:ale_haskell_floskell_executable *g:ale_haskell_floskell_executable*
This variable can be changed to use a different executable for floskell.
+
===============================================================================
ghc *ale-haskell-ghc*
@@ -32,6 +34,7 @@ g:ale_haskell_ghc_options *g:ale_haskell_ghc_options*
This variable can be changed to modify flags given to ghc.
+
===============================================================================
ghc-mod *ale-haskell-ghc-mod*
@@ -42,6 +45,7 @@ g:ale_haskell_ghc_mod_executable *g:ale_haskell_ghc_mod_executable*
This variable can be changed to use a different executable for ghc-mod.
+
===============================================================================
cabal-ghc *ale-haskell-cabal-ghc*
@@ -53,6 +57,7 @@ g:ale_haskell_cabal_ghc_options *g:ale_haskell_cabal_ghc_options*
This variable can be changed to modify flags given to ghc through cabal
exec.
+
===============================================================================
hdevtools *ale-haskell-hdevtools*
@@ -87,6 +92,18 @@ g:ale_haskell_hfmt_executable *g:ale_haskell_hfmt_executable*
This variable can be changed to use a different executable for hfmt.
+
+===============================================================================
+hindent *ale-haskell-hindent*
+
+g:ale_haskell_hindent_executable *g:ale_haskell_hindent_executable*
+ *b:ale_haskell_hindent_executable*
+ Type: |String|
+ Default: `'hindent'`
+
+ This variable can be changed to use a different executable for hindent.
+
+
===============================================================================
hlint *ale-haskell-hlint*
@@ -106,6 +123,7 @@ g:ale_haskell_hlint_options g:ale_haskell_hlint_options
This variable can be used to pass extra options to the underlying hlint
executable.
+
===============================================================================
stack-build *ale-haskell-stack-build*
@@ -117,6 +135,7 @@ g:ale_haskell_stack_build_options *g:ale_haskell_stack_build_options*
We default to using `'--fast'`. Since Stack generates binaries, your
programs will be slower unless you separately rebuild them outside of ALE.
+
===============================================================================
stack-ghc *ale-haskell-stack-ghc*
@@ -128,6 +147,7 @@ g:ale_haskell_stack_ghc_options *g:ale_haskell_stack_ghc_options*
This variable can be changed to modify flags given to ghc through `stack
ghc`
+
===============================================================================
stylish-haskell *ale-haskell-stylish-haskell*
@@ -139,6 +159,7 @@ g:ale_haskell_stylish_haskell_executable
This variable can be changed to use a different executable for stylish-haskell.
+
===============================================================================
hie *ale-haskell-hie*
@@ -150,5 +171,6 @@ g:ale_haskell_hie_executable *g:ale_haskell_hie_executable*
This variable can be changed to use a different executable for the haskell
ide engine. i.e. `'hie-wrapper'`
+
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt
index d39aaf7e..1b1202b9 100644
--- a/doc/ale-supported-languages-and-tools.txt
+++ b/doc/ale-supported-languages-and-tools.txt
@@ -14,6 +14,7 @@ Notes:
* Ada
* `gcc`
+ * `gnatpp`
* Ansible
* `ansible-lint`
* API Blueprint
@@ -102,6 +103,7 @@ Notes:
* Cython (pyrex filetype)
* `cython`
* D
+ * `dfmt`
* `dls`
* `dmd`
* `uncrustify`
@@ -182,6 +184,7 @@ Notes:
* `hdevtools`
* `hfmt`
* `hie`
+ * `hindent`
* `hlint`
* `stack-build`!!
* `stack-ghc`
diff --git a/doc/ale.txt b/doc/ale.txt
index 5541236f..43e124a2 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -341,6 +341,17 @@ completion source for Deoplete is named `'ale'`, and should enabled
automatically if Deoplete is enabled and configured correctly. Deoplete
integration should not be combined with ALE's own implementation.
+ *ale-asyncomplete-integration*
+
+ALE additionally integrates with asyncomplete.vim for offering automatic
+completion data. ALE's asyncomplete source requires registration and should
+use the defaults provided by the|asyncomplete#sources#ale#get_source_options| function >
+
+ " Use ALE's function for asyncomplete defaults
+ au User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#ale#get_source_options({
+ \ 'priority': 10, " Provide your own overrides here
+ \ }))
+>
ALE also offers its own completion implementation, which does not require any
other plugins. Suggestions will be made while you type after completion is
enabled. ALE's own completion implementation can be enabled by setting
@@ -1426,8 +1437,8 @@ g:ale_set_signs *g:ale_set_signs*
|ALEWarningLine| - All items with `'type': 'W'`
|ALEInfoLine| - All items with `'type': 'I'`
- With Neovim 0.3.2 or higher, ALE uses `numhl` option to highlight 'number'
- column. It uses the following highlight groups.
+ With Neovim 0.3.2 or higher, ALE can use the `numhl` option to highlight the
+ 'number' column. It uses the following highlight groups.
|ALEErrorSignLineNr| - Items with `'type': 'E'`
|ALEWarningSignLineNr| - Items with `'type': 'W'`
@@ -1435,6 +1446,9 @@ g:ale_set_signs *g:ale_set_signs*
|ALEStyleErrorSignLineNr| - Items with `'type': 'E'` and `'sub_type': 'style'`
|ALEStyleWarningSignLineNr| - Items with `'type': 'W'` and `'sub_type': 'style'`
+ To enable line number highlighting |g:ale_sign_highlight_linenrs| must be
+ set to `1` before ALE is loaded.
+
The markers for the highlights can be customized with the following options:
|g:ale_sign_error|
@@ -1541,6 +1555,16 @@ g:ale_sign_warning *g:ale_sign_warning*
The sign for warnings in the sign gutter.
+g:ale_sign_highlight_linenrs *g:ale_sign_highlight_linenrs*
+
+ Type: |Number|
+ Default: `0`
+
+ When set to `1`, this option enables highlighting problems on the 'number'
+ column in Vim versions that support `numhl` highlights. This option must be
+ configured before ALE is loaded.
+
+
g:ale_update_tagstack *g:ale_update_tagstack*
*b:ale_update_tagstack*
Type: |Number|
@@ -1943,6 +1967,14 @@ g:ale_languagetool_executable *g:ale_languagetool_executable*
The executable to run for languagetool.
+g:ale_languagetool_options *g:ale_languagetool_options*
+ *b:ale_languagetool_options*
+ Type: |String|
+ Default: `'--autoDetect'`
+
+ This variable can be set to pass additional options to languagetool.
+
+
-------------------------------------------------------------------------------
7.3. Options for write-good *ale-write-good-options*
@@ -1981,6 +2013,7 @@ documented in additional help files.
ada.....................................|ale-ada-options|
gcc...................................|ale-ada-gcc|
+ gnatpp................................|ale-ada-gnatpp|
ansible.................................|ale-ansible-options|
ansible-lint..........................|ale-ansible-ansible-lint|
asciidoc................................|ale-asciidoc-options|
@@ -2041,6 +2074,7 @@ documented in additional help files.
nvcc..................................|ale-cuda-nvcc|
clang-format..........................|ale-cuda-clangformat|
d.......................................|ale-d-options|
+ dfmt..................................|ale-d-dfmt|
dls...................................|ale-d-dls|
uncrustify............................|ale-d-uncrustify|
dart....................................|ale-dart-options|
@@ -2107,6 +2141,7 @@ documented in additional help files.
cabal-ghc.............................|ale-haskell-cabal-ghc|
hdevtools.............................|ale-haskell-hdevtools|
hfmt..................................|ale-haskell-hfmt|
+ hindent...............................|ale-haskell-hindent|
hlint.................................|ale-haskell-hlint|
stack-build...........................|ale-haskell-stack-build|
stack-ghc.............................|ale-haskell-stack-ghc|
diff --git a/supported-tools.md b/supported-tools.md
index 6cb9f418..d94da030 100644
--- a/supported-tools.md
+++ b/supported-tools.md
@@ -23,6 +23,7 @@ formatting.
* Ada
* [gcc](https://gcc.gnu.org)
+ * [gnatpp](https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/gnat_utility_programs.html#the-gnat-pretty-printer-gnatpp) :floppy_disk:
* Ansible
* [ansible-lint](https://github.com/willthames/ansible-lint)
* API Blueprint
@@ -111,6 +112,7 @@ formatting.
* Cython (pyrex filetype)
* [cython](http://cython.org/)
* D
+ * [dfmt](https://github.com/dlang-community/dfmt)
* [dls](https://github.com/d-language-server/dls)
* [dmd](https://dlang.org/dmd-linux.html)
* [uncrustify](https://github.com/uncrustify/uncrustify)
@@ -125,8 +127,8 @@ formatting.
* [hadolint](https://github.com/hadolint/hadolint)
* Elixir
* [credo](https://github.com/rrrene/credo)
- * [dialyxir](https://github.com/jeremyjh/dialyxir)
- * [dogma](https://github.com/lpil/dogma)
+ * [dialyxir](https://github.com/jeremyjh/dialyxir) :floppy_disk:
+ * [dogma](https://github.com/lpil/dogma) :floppy_disk:
* [elixir-ls](https://github.com/JakeBecker/elixir-ls) :warning:
* [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk:
* Elm
@@ -191,6 +193,7 @@ formatting.
* [hdevtools](https://hackage.haskell.org/package/hdevtools)
* [hfmt](https://github.com/danstiner/hfmt)
* [hie](https://github.com/haskell/haskell-ide-engine)
+ * [hindent](https://hackage.haskell.org/package/hindent)
* [hlint](https://hackage.haskell.org/package/hlint)
* [stack-build](https://haskellstack.org/) :floppy_disk:
* [stack-ghc](https://haskellstack.org/)
diff --git a/test/ada_files/testfile.adb b/test/ada_files/testfile.adb
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/ada_files/testfile.adb
diff --git a/test/command_callback/python_paths/with_virtualenv/subdir/foo/bar.pyi b/test/command_callback/python_paths/with_virtualenv/subdir/foo/bar.pyi
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/python_paths/with_virtualenv/subdir/foo/bar.pyi
diff --git a/test/command_callback/test_languagetool_command_callback.vader b/test/command_callback/test_languagetool_command_callback.vader
index a79662b9..ff6b2064 100644
--- a/test/command_callback/test_languagetool_command_callback.vader
+++ b/test/command_callback/test_languagetool_command_callback.vader
@@ -12,4 +12,11 @@ Execute(Should be able to set a custom executable):
let g:ale_languagetool_executable = 'foobar'
AssertLinter 'foobar' , ale#Escape('foobar')
- \ . ' --autoDetect %s'
+ \ . ' --autoDetect %s'
+
+Execute(Should be able to include custom languagetool options):
+ let g:ale_languagetool_options = '--language en'
+
+ " is now 'foobar' based on above global
+ AssertLinter 'foobar', ale#Escape('foobar')
+ \ . ' --language en %s'
diff --git a/test/completion/test_completion_events.vader b/test/completion/test_completion_events.vader
index 6bc0035e..5672f8e5 100644
--- a/test/completion/test_completion_events.vader
+++ b/test/completion/test_completion_events.vader
@@ -62,6 +62,10 @@ After:
delfunction CheckCompletionCalled
+ if exists('*CompleteCallback')
+ delfunction CompleteCallback
+ endif
+
" Stop any timers we left behind.
" This stops the tests from failing randomly.
call ale#completion#StopTimer()
@@ -333,6 +337,30 @@ Execute(b:ale_completion_info should be set up correctly for other sources):
\ b:ale_completion_info
Assert !exists('b:ale_completion_result')
+Execute(b:ale_completion_info should be set up correctly when requesting completions via callback):
+ let b:ale_completion_result = []
+ call setpos('.', [bufnr(''), 3, 14, 0])
+
+ function! CompleteCallback() abort
+ echo 'Called'
+ endfunction
+
+
+ call ale#completion#GetCompletions('ale-callback', {'callback': funcref('CompleteCallback')})
+
+ AssertEqual
+ \ {
+ \ 'request_id': 0,
+ \ 'conn_id': 0,
+ \ 'column': 14,
+ \ 'line_length': 14,
+ \ 'line': 3,
+ \ 'prefix': 'ab',
+ \ 'source': 'ale-callback',
+ \ },
+ \ b:ale_completion_info
+ Assert !exists('b:ale_completion_result')
+
Execute(The correct keybinds should be configured):
redir => g:output
silent map <Plug>(ale_show_completion_menu)
diff --git a/test/d_files/test.d b/test/d_files/test.d
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/d_files/test.d
diff --git a/test/fixers/test_black_fixer_callback.vader b/test/fixers/test_black_fixer_callback.vader
index 25ad05db..75864479 100644
--- a/test/fixers/test_black_fixer_callback.vader
+++ b/test/fixers/test_black_fixer_callback.vader
@@ -36,6 +36,14 @@ Execute(The black callback should include options):
\ {'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --some-option -' },
\ ale#fixers#black#Fix(bufnr(''))
+Execute(The black callback should include --pyi for .pyi files):
+ let g:ale_python_black_change_directory = 0
+
+ silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.pyi')
+ AssertEqual
+ \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --pyi -' },
+ \ ale#fixers#black#Fix(bufnr(''))
+
Execute(Pipenv is detected when python_black_auto_pipenv is set):
let g:ale_python_black_auto_pipenv = 1
let g:ale_python_black_change_directory = 0
diff --git a/test/fixers/test_dfmt_fixer_callback.vader b/test/fixers/test_dfmt_fixer_callback.vader
new file mode 100644
index 00000000..5ecb56e6
--- /dev/null
+++ b/test/fixers/test_dfmt_fixer_callback.vader
@@ -0,0 +1,40 @@
+Before:
+ Save g:ale_d_dfmt_executable
+ Save g:ale_d_dfmt_options
+
+ " Use an invalid global executable, so we don't match it.
+ let g:ale_d_dfmt_executable = 'xxxinvalid'
+ let g:ale_d_dfmt_options = ''
+
+ call ale#test#SetDirectory('/testplugin/test/fixers')
+
+After:
+ Restore
+
+ call ale#test#RestoreDirectory()
+
+Execute(The dfmt callback should return the correct default values):
+ call ale#test#SetFilename('../d_files/test.d')
+
+ AssertEqual
+ \ {
+ \ 'read_temporary_file': 1,
+ \ 'command': ale#Escape('xxxinvalid')
+ \ . ' -i'
+ \ . ' %t',
+ \ },
+ \ ale#fixers#dfmt#Fix(bufnr(''))
+
+Execute(The dfmt callback should include custom dfmt options):
+ let g:ale_d_dfmt_options = "--space-after-cast"
+ call ale#test#SetFilename('../d_files/test.d')
+
+ AssertEqual
+ \ {
+ \ 'read_temporary_file': 1,
+ \ 'command': ale#Escape('xxxinvalid')
+ \ . ' -i'
+ \ . ' ' . g:ale_d_dfmt_options
+ \ . ' %t',
+ \ },
+ \ ale#fixers#dfmt#Fix(bufnr(''))
diff --git a/test/fixers/test_gnatpp_fixer_callback.vader b/test/fixers/test_gnatpp_fixer_callback.vader
new file mode 100644
index 00000000..a2bf898e
--- /dev/null
+++ b/test/fixers/test_gnatpp_fixer_callback.vader
@@ -0,0 +1,28 @@
+Before:
+ call ale#assert#SetUpFixerTest('ada', 'gnatpp')
+
+After:
+ " Reset fixers, variables, etc.
+ "
+ " Vader's 'Restore' command will be called here.
+ call ale#assert#TearDownFixerTest()
+
+Execute(The default command should be correct):
+ call ale#test#SetFilename('../ada_files/testfile.adb')
+
+ AssertFixer
+ \ {
+ \ 'command': ale#Escape(g:ale_ada_gnatpp_executable) .' %t',
+ \ 'read_temporary_file': 1,
+ \ }
+
+Execute(The version check should be correct):
+ call ale#test#SetFilename('../ada_files/testfile.adb')
+ let g:ale_ada_gnatpp_options = '--no-alignment'
+
+ AssertFixer
+ \ {
+ \ 'command': ale#Escape(g:ale_ada_gnatpp_executable)
+ \ . ' --no-alignment %t',
+ \ 'read_temporary_file': 1,
+ \ }
diff --git a/test/fixers/test_hindent_fixer_callback.vader b/test/fixers/test_hindent_fixer_callback.vader
new file mode 100644
index 00000000..2e5a8b9f
--- /dev/null
+++ b/test/fixers/test_hindent_fixer_callback.vader
@@ -0,0 +1,18 @@
+Before:
+ call ale#test#SetDirectory('/testplugin/test/fixers')
+
+After:
+ Restore
+
+ call ale#test#RestoreDirectory()
+
+Execute(The hindent callback should return the correct default values):
+ call ale#test#SetFilename('../haskell_files/testfile.hs')
+
+ AssertEqual
+ \ {
+ \ 'read_temporary_file': 1,
+ \ 'command': ale#Escape('hindent')
+ \ . ' %t',
+ \ },
+ \ ale#fixers#hindent#Fix(bufnr(''))
diff --git a/test/handler/test_shell_handler.vader b/test/handler/test_shell_handler.vader
index 2465f179..c61cf37d 100644
--- a/test/handler/test_shell_handler.vader
+++ b/test/handler/test_shell_handler.vader
@@ -40,3 +40,138 @@ Execute(The shell handler should parse lines correctly):
\ 'qfm:22: :11: :33: :44:',
\ 'foo.sh: syntax error at line 9: `done'' unexpected',
\ ])
+
+Execute(The shell handler should parse Simplified Chinese lines correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 0,
+ \ 'text': '未预期的符号“done”附近有语法错误',
+ \ },
+ \ {
+ \ 'lnum': 90,
+ \ 'text': '寻找匹配的“"”时遇到了未预期的文件结束符',
+ \ },
+ \ {
+ \ 'lnum': 111,
+ \ 'text': '语法错误: 未预期的文件结尾',
+ \ },
+ \ {
+ \ 'lnum': 22,
+ \ 'text': ':11: :33: :44:',
+ \ },
+ \ ],
+ \ ale_linters#sh#shell#Handle(347, [
+ \ '/tmp/nvimWL5sOL/2/a.sh:行0: 未预期的符号“done”附近有语法错误',
+ \ '/tmp/nvimWL5sOL/2/a.sh:行90: 寻找匹配的“"”时遇到了未预期的文件结束符',
+ \ '/tmp/nvimWL5sOL/2/a.sh:行111: 语法错误: 未预期的文件结尾',
+ \ '/tmp/nvimWL5sOL/2/a.sh:行22: :11: :33: :44:',
+ \ ])
+
+Execute(The shell handler should parse Traditional Chinese lines correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 0,
+ \ 'text': '未預期的字組「(」附近有語法錯誤',
+ \ },
+ \ {
+ \ 'lnum': 90,
+ \ 'text': '尋找匹配的「"」時遇到了未預期的檔案結束符',
+ \ },
+ \ {
+ \ 'lnum': 111,
+ \ 'text': '語法錯誤: 未預期的檔案結尾',
+ \ },
+ \ {
+ \ 'lnum': 22,
+ \ 'text': ':11: :33: :44:',
+ \ },
+ \ ],
+ \ ale_linters#sh#shell#Handle(347, [
+ \ '/tmp/nvimWL5sOL/2/a.sh: 列 0: 未預期的字組「(」附近有語法錯誤',
+ \ '/tmp/nvimWL5sOL/2/a.sh: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符',
+ \ '/tmp/nvimWL5sOL/2/a.sh: 列 111: 語法錯誤: 未預期的檔案結尾',
+ \ '/tmp/nvimWL5sOL/2/a.sh: 列 22: :11: :33: :44:',
+ \ ])
+
+Execute(The shell handler should parse Japanese lines correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 0,
+ \ 'text': "予期しないトークン `(' 周辺に構文エラーがあります",
+ \ },
+ \ {
+ \ 'lnum': 90,
+ \ 'text': "予期しないトークン `done' 周辺に構文エラーがあります",
+ \ },
+ \ {
+ \ 'lnum': 111,
+ \ 'text': "対応する `\"' を探索中に予期しないファイル終了 (EOF) です",
+ \ },
+ \ {
+ \ 'lnum': 22,
+ \ 'text': ':11: :33: :44:',
+ \ },
+ \ ],
+ \ ale_linters#sh#shell#Handle(347, [
+ \ "/tmp/nvimWL5sOL/2/a.sh: 行 0: 予期しないトークン `(' 周辺に構文エラーがあります",
+ \ "/tmp/nvimWL5sOL/2/a.sh: 行 90: 予期しないトークン `done' 周辺に構文エラーがあります",
+ \ "/tmp/nvimWL5sOL/2/a.sh: 行 111: 対応する `\"' を探索中に予期しないファイル終了 (EOF) です",
+ \ "/tmp/nvimWL5sOL/2/a.sh: 行 22: :11: :33: :44:",
+ \ ])
+
+Execute(The shell handler should parse Greek lines correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 0,
+ \ 'text': 'συντακτικό σφάλμα κοντά στο μη αναμενόμενο σύμβολο «done»',
+ \ },
+ \ {
+ \ 'lnum': 90,
+ \ 'text': 'syntax error: μη αναμενόμενο τέλος αρχείου',
+ \ },
+ \ {
+ \ 'lnum': 111,
+ \ 'text': 'μη αναμενόμενο EOF κατά την αναζήτηση «"»',
+ \ },
+ \ {
+ \ 'lnum': 22,
+ \ 'text': ':11: :33: :44:',
+ \ },
+ \ ],
+ \ ale_linters#sh#shell#Handle(347, [
+ \ '/tmp/nvimWL5sOL/2/a.sh: γραμμή 0: συντακτικό σφάλμα κοντά στο μη αναμενόμενο σύμβολο «done»',
+ \ '/tmp/nvimWL5sOL/2/a.sh: γραμμή 90: syntax error: μη αναμενόμενο τέλος αρχείου',
+ \ '/tmp/nvimWL5sOL/2/a.sh: γραμμή 111: μη αναμενόμενο EOF κατά την αναζήτηση «"»',
+ \ "/tmp/nvimWL5sOL/2/a.sh: γραμμή 22: :11: :33: :44:",
+ \ ])
+
+Execute(The shell handler should parse Russian lines correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 0,
+ \ 'text': 'синтаксическая ошибка рядом с неожиданным маркером «done»',
+ \ },
+ \ {
+ \ 'lnum': 90,
+ \ 'text': 'синтаксическая ошибка: неожиданный конец файла',
+ \ },
+ \ {
+ \ 'lnum': 111,
+ \ 'text': 'неожиданный конец файла во время поиска «"»',
+ \ },
+ \ {
+ \ 'lnum': 22,
+ \ 'text': ':11: :33: :44:',
+ \ },
+ \ ],
+ \ ale_linters#sh#shell#Handle(347, [
+ \ '/tmp/nvimWL5sOL/2/a.sh: строка 0: синтаксическая ошибка рядом с неожиданным маркером «done»',
+ \ '/tmp/nvimWL5sOL/2/a.sh: строка 90: синтаксическая ошибка: неожиданный конец файла',
+ \ '/tmp/nvimWL5sOL/2/a.sh: строка 111: неожиданный конец файла во время поиска «"»',
+ \ '/tmp/nvimWL5sOL/2/a.sh: строка 22: :11: :33: :44:',
+ \ ])
diff --git a/test/script/check-toc b/test/script/check-toc
index f3a57ed2..87a61262 100755
--- a/test/script/check-toc
+++ b/test/script/check-toc
@@ -35,7 +35,7 @@ sed -n "$toc_start_line,$toc_end_line"p doc/ale.txt \
> "$toc_file"
# Get all of the doc files in a natural sorted order.
-doc_files="$(/bin/ls -1v doc | grep ^ale- | sed 's/^/doc\//' | paste -sd ' ' -)"
+doc_files="$(/usr/bin/env ls -1v doc | grep ^ale- | sed 's/^/doc\//' | paste -sd ' ' -)"
# shellcheck disable=SC2086
grep -h '\*ale-.*-options\|^[a-z].*\*ale-.*\*$' $doc_files \
diff --git a/test/test_ale_info.vader b/test/test_ale_info.vader
index e1208679..2bc8c635 100644
--- a/test/test_ale_info.vader
+++ b/test/test_ale_info.vader
@@ -47,6 +47,7 @@ Before:
Save g:ale_sign_style_error
Save g:ale_sign_style_warning
Save g:ale_sign_warning
+ Save g:ale_sign_highlight_linenrs
Save g:ale_statusline_format
Save g:ale_type_map
Save g:ale_use_global_executables
@@ -102,6 +103,7 @@ Before:
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
+ let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = ['%d error(s)', '%d warning(s)', 'OK']
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
@@ -178,6 +180,7 @@ Before:
\ 'let g:ale_sign_style_error = ''>>''',
\ 'let g:ale_sign_style_warning = ''--''',
\ 'let g:ale_sign_warning = ''--''',
+ \ 'let g:ale_sign_highlight_linenrs = 0',
\ 'let g:ale_statusline_format = [''%d error(s)'', ''%d warning(s)'', ''OK'']',
\ 'let g:ale_type_map = {}',
\ 'let g:ale_use_global_executables = v:null',
diff --git a/test/test_ale_toggle.vader b/test/test_ale_toggle.vader
index d0bca329..a0763cb1 100644
--- a/test/test_ale_toggle.vader
+++ b/test/test_ale_toggle.vader
@@ -36,6 +36,7 @@ Before:
\ 'ALEEvents',
\ 'ALEHighlightBufferGroup',
\]
+ let g:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
function! ToggleTestCallback(buffer, output)
return [{
@@ -91,6 +92,7 @@ After:
unlet! g:expected_groups
unlet! b:ale_enabled
unlet! g:output
+ unlet! g:has_nvim_highlight
call ale#linter#Reset()
@@ -120,9 +122,14 @@ Execute(ALEToggle should reset everything and then run again):
" First check that everything is there...
AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule()
AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%'))
- AssertEqual
- \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
- \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+
+ " Only check the legacy matches if not using the new NeoVIM API.
+ if !g:has_nvim_highlight
+ AssertEqual
+ \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
+ \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+ endif
+
AssertEqual g:expected_groups, ParseAuGroups()
AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist
@@ -133,7 +140,11 @@ Execute(ALEToggle should reset everything and then run again):
Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed'
AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared'
AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared'
- AssertEqual [], getmatches(), 'The highlights were not cleared'
+
+ if !g:has_nvim_highlight
+ AssertEqual [], getmatches(), 'The highlights were not cleared'
+ endif
+
AssertEqual g:expected_groups, ParseAuGroups()
" Toggle ALE on, everything should be set up and run again.
@@ -142,9 +153,13 @@ Execute(ALEToggle should reset everything and then run again):
AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule()
AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%'))
- AssertEqual
- \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
- \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+
+ if !g:has_nvim_highlight
+ AssertEqual
+ \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
+ \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+ endif
+
AssertEqual g:expected_groups, ParseAuGroups()
AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist
@@ -228,9 +243,13 @@ Execute(ALEReset should reset everything for a buffer):
" First check that everything is there...
AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule()
AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%'))
- AssertEqual
- \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
- \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+
+ if !g:has_nvim_highlight
+ AssertEqual
+ \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
+ \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+ endif
+
AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist
" Now Toggle ALE off.
@@ -241,7 +260,10 @@ Execute(ALEReset should reset everything for a buffer):
Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed'
AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared'
AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared'
- AssertEqual [], getmatches(), 'The highlights were not cleared'
+
+ if !g:has_nvim_highlight
+ AssertEqual [], getmatches(), 'The highlights were not cleared'
+ endif
AssertEqual 1, g:ale_enabled
@@ -254,9 +276,13 @@ Execute(ALEToggleBuffer should reset everything and then run again):
" First check that everything is there...
AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule()
AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%'))
- AssertEqual
- \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
- \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+
+ if !g:has_nvim_highlight
+ AssertEqual
+ \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
+ \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+ endif
+
AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist
" Now Toggle ALE off.
@@ -266,7 +292,10 @@ Execute(ALEToggleBuffer should reset everything and then run again):
Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed'
AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared'
AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared'
- AssertEqual [], getmatches(), 'The highlights were not cleared'
+
+ if !g:has_nvim_highlight
+ AssertEqual [], getmatches(), 'The highlights were not cleared'
+ endif
" Toggle ALE on, everything should be set up and run again.
ALEToggleBuffer
@@ -274,9 +303,13 @@ Execute(ALEToggleBuffer should reset everything and then run again):
AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule()
AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%'))
- AssertEqual
- \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
- \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+
+ if !g:has_nvim_highlight
+ AssertEqual
+ \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
+ \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+ endif
+
AssertEqual g:expected_groups, ParseAuGroups()
AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist
@@ -325,9 +358,13 @@ Execute(ALEResetBuffer should reset everything for a buffer):
" First check that everything is there...
AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule()
AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%'))
- AssertEqual
- \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
- \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+
+ if !g:has_nvim_highlight
+ AssertEqual
+ \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}],
+ \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}')
+ endif
+
AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist
" Now Toggle ALE off.
@@ -338,7 +375,10 @@ Execute(ALEResetBuffer should reset everything for a buffer):
Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed'
AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared'
AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared'
- AssertEqual [], getmatches(), 'The highlights were not cleared'
+
+ if !g:has_nvim_highlight
+ AssertEqual [], getmatches(), 'The highlights were not cleared'
+ endif
AssertEqual 1, g:ale_enabled
AssertEqual 1, get(b:, 'ale_enabled', 1)
diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader
index 045554a3..8ae6f9dc 100644
--- a/test/test_c_flag_parsing.vader
+++ b/test/test_c_flag_parsing.vader
@@ -14,7 +14,7 @@ Execute(The CFlags parser should be able to parse include directives):
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
AssertEqual
- \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'),
+ \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')),
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -c file.c'])
AssertEqual
@@ -25,14 +25,14 @@ Execute(ParseCFlags should ignore -c and -o):
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
AssertEqual
- \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'),
+ \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')),
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -c file.c -o a.out'])
Execute(The CFlags parser should be able to parse macro directives):
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
AssertEqual
- \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
+ \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' -DTEST=1',
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=1 -c file.c'])
@@ -40,7 +40,7 @@ Execute(The CFlags parser should be able to parse macro directives with spaces):
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
AssertEqual
- \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
+ \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' -DTEST=$(( 2 * 4 ))',
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=$(( 2 * 4 )) -c file.c'])
@@ -48,14 +48,14 @@ Execute(The CFlags parser should be able to parse shell directives with spaces):
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
AssertEqual
- \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
+ \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=`date +%s` -c file.c'])
Execute(ParseCFlags should be able to parse flags with relative paths):
AssertEqual
- \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')
+ \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
@@ -67,8 +67,8 @@ Execute(ParseCFlags should be able to parse flags with relative paths):
Execute(ParseCFlags should be able to parse -Dgoal):
AssertEqual
\ '-Dgoal=9'
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
@@ -77,16 +77,30 @@ Execute(ParseCFlags should be able to parse -Dgoal):
\ . ' -DTEST=`date +%s` -c file.c'
\ )
+Execute(ParseCFlags should ignore -T and other arguments):
+ AssertEqual
+ \ '-Dgoal=9'
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' ' . '--sysroot=subdir'
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
+ \ . ' -DTEST=`date +%s`',
+ \ ale#c#ParseCFlags(
+ \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir --sysroot=subdir '
+ \ . '-I'. ale#path#Simplify('kernel/include')
+ \ . ' -DTEST=`date +%s` -c file.c'
+ \ )
+
Execute(ParseCFlags should handle paths with spaces in double quotes):
AssertEqual
\ '-Dgoal=9'
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/"dir with spaces"')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
- \ 'gcc -Dgoal=9 -Isubdir '
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . '-I"dir with spaces"' . ' -I'. ale#path#Simplify('kernel/include')
\ . ' -DTEST=`date +%s` -c file.c'
\ )
@@ -94,28 +108,29 @@ Execute(ParseCFlags should handle paths with spaces in double quotes):
Execute(ParseCFlags should handle paths with spaces in single quotes):
AssertEqual
\ '-Dgoal=9'
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. "/test_c_projects/makefile_project/'dir with spaces'")
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
- \ 'gcc -Dgoal=9 -Isubdir '
- \ . "-I'dir with spaces'" . ' -I'. ale#path#Simplify('kernel/include')
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
+ \ . '-I''dir with spaces''' . ' -I'. ale#path#Simplify('kernel/include')
\ . ' -DTEST=`date +%s` -c file.c'
\ )
Execute(ParseCFlags should handle paths with minuses):
AssertEqual
\ '-Dgoal=9'
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
- \ 'gcc -Dgoal=9 -Isubdir '
- \ . ' -Idir-with-dash'
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
+ \ . '-I''dir with spaces''' . ' -Idir-with-dash'
\ . ' -I'. ale#path#Simplify('kernel/include')
\ . ' -DTEST=`date +%s` -c file.c'
\ )
@@ -123,14 +138,17 @@ Execute(ParseCFlags should handle paths with minuses):
Execute(ParseCFlags should handle -D with minuses):
AssertEqual
\ '-Dgoal=9'
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' -Dmacro-with-dash'
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
- \ 'gcc -Dgoal=9 -Isubdir '
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . '-Dmacro-with-dash '
+ \ . '-I''dir with spaces''' . ' -Idir-with-dash'
\ . ' -I'. ale#path#Simplify('kernel/include')
\ . ' -DTEST=`date +%s` -c file.c'
\ )
@@ -138,11 +156,16 @@ Execute(ParseCFlags should handle -D with minuses):
Execute(ParseCFlags should handle flags at the end of the line):
AssertEqual
\ '-Dgoal=9'
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')
- \ . ' ' . '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'),
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' -Dmacro-with-dash'
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
- \ 'gcc -Dgoal=9 -Isubdir '
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
+ \ . '-Dmacro-with-dash '
+ \ . '-I''dir with spaces''' . ' -Idir-with-dash'
\ . ' -I'. ale#path#Simplify('kernel/include')
\ )
@@ -156,14 +179,14 @@ Execute(ParseCompileCommandsFlags should parse some basic flags):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
AssertEqual
- \ '-I/usr/include/xmms2',
+ \ '-I ' . ale#path#Simplify('/usr/include/xmms2'),
\ ale#c#ParseCompileCommandsFlags(bufnr(''), { "xmms2-mpris.c": [
\ {
- \ 'directory': '/foo/bar/xmms2-mpris',
- \ 'command': '/usr/bin/cc -I' . '/usr/include/xmms2'
+ \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
+ \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
- \ . ' -c ' . '/foo/bar/xmms2-mpris/src/xmms2-mpris.c',
- \ 'file': '/foo/bar/xmms2-mpris/src/xmms2-mpris.c',
+ \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
+ \ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ },
\ ] }, {})
@@ -183,14 +206,14 @@ Execute(ParseCompileCommandsFlags should fall back to files in the same director
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
AssertEqual
- \ '-I/usr/include/xmms2',
+ \ '-I ' . ale#path#Simplify('/usr/include/xmms2'),
\ ale#c#ParseCompileCommandsFlags(bufnr(''), {}, { "src": [
\ {
- \ 'directory': '/foo/bar/xmms2-mpris',
- \ 'command': '/usr/bin/cc -I' . '/usr/include/xmms2'
+ \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
+ \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
- \ . ' -c ' . '/foo/bar/xmms2-mpris/src/xmms2-mpris.c',
- \ 'file': (has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c',
+ \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
+ \ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
\ },
\ ] })
@@ -198,7 +221,7 @@ Execute(ParseCompileCommandsFlags should take commands from matching .c files fo
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h'))
AssertEqual
- \ '-I/usr/include/xmms2',
+ \ '-I /usr/include/xmms2',
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
@@ -220,7 +243,7 @@ Execute(ParseCompileCommandsFlags should take commands from matching .cpp files
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.hpp'))
AssertEqual
- \ '-I/usr/include/xmms2',
+ \ '-I /usr/include/xmms2',
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
@@ -242,7 +265,7 @@ Execute(ParseCompileCommandsFlags should take commands from matching .cpp files
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h'))
AssertEqual
- \ '-I/usr/include/xmms2',
+ \ '-I /usr/include/xmms2',
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
@@ -282,13 +305,64 @@ Execute(ParseCompileCommandsFlags should not take commands from .c files for .h
\ },
\ )
+Execute(ParseCFlags should not merge flags):
+ AssertEqual
+ \ '-Dgoal=9'
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
+ \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
+ \ ale#c#ParseCFlags(
+ \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
+ \ . 'subdir/somedep1.o ' . 'subdir/somedep2.o '
+ \ . '-I''dir with spaces''' . ' -Idir-with-dash '
+ \ . 'subdir/somedep3.o ' . 'subdir/somedep4.o '
+ \ . ' -I'. ale#path#Simplify('kernel/include') . ' '
+ \ . 'subdir/somedep5.o ' . 'subdir/somedep6.o '
+ \ )
+
Execute(ParseCFlags should handle parenthesis and quotes):
AssertEqual
- \ '-Dgoal=9 -Dtest1="('' '')" file1.o -Dtest2=''(` `)'' file2.o -Dtest3=`(" ")` file3.o',
+ \ '-Dgoal=9 -Dtest1="('' '')" -Dtest2=''(` `)'' -Dtest3=`(" ")`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
- \ 'gcc -Dgoal=9 '
+ \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla '
\ . '-Dtest1="('' '')" file1.o '
\ . '-Dtest2=''(` `)'' file2.o '
\ . '-Dtest3=`(" ")` file3.o '
\ )
+
+Execute(CFlags we want to pass):
+ AssertEqual
+ \ '-I ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/inc'))
+ \ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/include'))
+ \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incquote'))
+ \ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incsystem'))
+ \ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter'))
+ \ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2'
+ \ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
+ \ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir'
+ \ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
+ \ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++'
+ \ . ' -iplugindir=dir -march=native -w',
+ \ ale#c#ParseCFlags(
+ \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
+ \ 'gcc'
+ \ . ' -Iinc -I include -iquote incquote -isystem incsystem -idirafter incafter'
+ \ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2'
+ \ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
+ \ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir'
+ \ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
+ \ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++'
+ \ . ' -iplugindir=dir -march=native -w'
+ \ )
+
+Execute(CFlags we dont want to pass):
+ AssertEqual
+ \ '',
+ \ ale#c#ParseCFlags(
+ \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
+ \ 'gcc -Wl,option -Wa,option -Wp,option filename.c somelib.a '
+ \ . '-fdump-file=name -fdiagnostics-arg -fno-show-column'
+ \ )
diff --git a/test/test_highlight_placement.vader b/test/test_highlight_placement.vader
index 87ac6073..c062018b 100644
--- a/test/test_highlight_placement.vader
+++ b/test/test_highlight_placement.vader
@@ -8,6 +8,8 @@ Before:
Save g:ale_set_quickfix
Save g:ale_set_signs
+ runtime autoload/ale/highlight.vim
+
let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks
let g:ale_set_highlights = 1
@@ -42,16 +44,54 @@ Before:
\]
endfunction
+ let g:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
+ let g:nvim_highlight_matches = {}
+
+ function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
+ if a:line_end != -1
+ throw 'nvim api behavior not supported'
+ endif
+
+ let l:matches = get(g:nvim_highlight_matches, a:buffer, [])
+ call filter(
+ \ l:matches,
+ \ {_, val -> val.pos1[0] < (a:line_start + 1) },
+ \)
+ endfunction
+
+ function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
+ if a:col_end == -1
+ throw 'nvim api behavior not supported'
+ endif
+
+ let l:matches = get(g:nvim_highlight_matches, a:buffer, [])
+ let g:nvim_highlight_matches[a:buffer] = l:matches
+
+ let l:new_match = {
+ \ 'group': a:hl_group,
+ \ 'priority': 10,
+ \ 'pos1': [a:line + 1, a:col_start + 1, a:col_end - a:col_start],
+ \}
+
+ call add(l:matches, l:new_match)
+ " sort by line number to emulate getmatches faithfully
+ call sort(l:matches, {m1, m2 -> m1.pos1[0] - m2.pos1[0]})
+ endfunction
+
" We don't care what the IDs are, just that we have some matches.
" The IDs are generated.
function! GetMatchesWithoutIDs() abort
- let l:list = getmatches()
+ if g:has_nvim_highlight
+ return get(g:nvim_highlight_matches, bufnr(''), [])
+ else
+ let l:list = getmatches()
- for l:item in l:list
- call remove(l:item, 'id')
- endfor
+ for l:item in l:list
+ call remove(l:item, 'id')
+ endfor
- return l:list
+ return l:list
+ endif
endfunction
call ale#linter#Define('testft', {
@@ -68,6 +108,8 @@ After:
unlet! g:ale_run_synchronously_callbacks
unlet! g:items
unlet! b:ale_enabled
+ unlet! g:has_nvim_highlight
+ unlet! g:nvim_highlight_matches
delfunction GenerateResults
call ale#linter#Reset()
@@ -75,6 +117,8 @@ After:
sign unplace *
highlight clear SomeOtherGroup
+ runtime autoload/ale/highlight.vim
+
Given testft(A Javscript file with warnings/errors):
foo
bar
@@ -102,9 +146,12 @@ Execute(Highlights set by ALE should be removed when buffer cleanup is done):
\ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2},
\])
- AssertEqual
- \ [{'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]}],
- \ GetMatchesWithoutIDs()
+ if !g:has_nvim_highlight
+ " This check doesn't work with the new API, for some reason.
+ AssertEqual
+ \ [{'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]}],
+ \ GetMatchesWithoutIDs()
+ endif
call ale#engine#Cleanup(bufnr('%'))
@@ -145,31 +192,53 @@ Execute(Only ALE highlights should be restored when buffers are restored):
call matchaddpos('SomeOtherGroup', [[1, 1, 1]])
" We should have both highlights.
- AssertEqual
- \ [
- \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]},
- \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]},
- \ ],
- \ GetMatchesWithoutIDs()
+ if g:has_nvim_highlight
+ " When the newer NeoVim API is used, we don't have to worry about
+ " other highlights, namespacing is available.
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]},
+ \ ],
+ \ GetMatchesWithoutIDs()
+ else
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]},
+ \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]},
+ \ ],
+ \ sort(GetMatchesWithoutIDs(), {m1, m2 -> m1.group < m2.group ? -1 : 1})
+ endif
call ale#highlight#BufferHidden(bufnr('%'))
" We should remove our highlight, but not the other one.
- AssertEqual
- \ [
- \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}
- \ ],
- \ GetMatchesWithoutIDs()
+ if g:has_nvim_highlight
+ AssertEqual [], GetMatchesWithoutIDs()
+ else
+ AssertEqual
+ \ [
+ \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}
+ \ ],
+ \ GetMatchesWithoutIDs()
+ endif
call ale#highlight#UpdateHighlights()
" Our highlight should apper again.
- AssertEqual
- \ [
- \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]},
- \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]},
- \ ],
- \ GetMatchesWithoutIDs()
+ if g:has_nvim_highlight
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]},
+ \ ],
+ \ GetMatchesWithoutIDs()
+ else
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]},
+ \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]},
+ \ ],
+ \ sort(GetMatchesWithoutIDs(), {m1, m2 -> m1.group < m2.group ? -1 : 1})
+ endif
Execute(Higlight end columns should set an appropriate size):
call ale#highlight#SetHighlights(bufnr('%'), [
@@ -216,32 +285,67 @@ Execute(Highlighting should support errors spanning many lines):
call ale#highlight#SetHighlights(bufnr(''), g:items)
- " We should set 2 highlights for the item, as we can only add 8 at a time.
- AssertEqual
- \ [
- \ {
- \ 'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1073741824],
- \ 'pos2': [2], 'pos3': [3], 'pos4': [4], 'pos5': [5], 'pos6': [6],
- \ 'pos7': [7], 'pos8': [8],
- \ },
- \ {
- \ 'group': 'ALEError', 'priority': 10,
- \ 'pos1': [9], 'pos2': [10, 1, 3]
- \ },
- \ ],
- \ GetMatchesWithoutIDs()
+ if g:has_nvim_highlight
+ " The newer NeoVim highlight API produces different output.
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [2, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [4, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [5, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [6, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [7, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [8, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [9, 1, 1073741824]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [10, 1, 3]},
+ \ ],
+ \ GetMatchesWithoutIDs()
+ else
+ " We should set 2 highlights for the item, as we can only add 8 at a time.
+ AssertEqual
+ \ [
+ \ {
+ \ 'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1073741824],
+ \ 'pos2': [2], 'pos3': [3], 'pos4': [4], 'pos5': [5], 'pos6': [6],
+ \ 'pos7': [7], 'pos8': [8],
+ \ },
+ \ {
+ \ 'group': 'ALEError', 'priority': 10,
+ \ 'pos1': [9], 'pos2': [10, 1, 3]
+ \ },
+ \ ],
+ \ GetMatchesWithoutIDs()
+ endif
Execute(Highlights should always be cleared when the buffer highlight list is empty):
- " Add our highlights and something else.
- call matchaddpos('ALEError', [[1, 1, 1]])
- call matchaddpos('SomeOtherGroup', [[1, 1, 1]])
+ if g:has_nvim_highlight
+ " The newer API uses namespacing. We'll emulate it here.
+ call ale#highlight#nvim_buf_add_highlight(
+ \ bufnr(''),
+ \ 1,
+ \ 'ALEError',
+ \ 0,
+ \ 0,
+ \ 1,
+ \)
+
+ AssertEqual
+ \ [{'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}],
+ \ GetMatchesWithoutIDs()
+ else
+ " Add our highlights and something else.
+ call matchaddpos('ALEError', [[1, 1, 1]])
+ call matchaddpos('SomeOtherGroup', [[1, 1, 1]])
+
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]},
+ \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]},
+ \ ],
+ \ GetMatchesWithoutIDs()
+ endif
- AssertEqual
- \ [
- \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]},
- \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]},
- \ ],
- \ GetMatchesWithoutIDs()
" Set the List we use for holding highlights for buffers.
let b:ale_highlight_items = []
@@ -251,11 +355,13 @@ Execute(Highlights should always be cleared when the buffer highlight list is em
call ale#highlight#UpdateHighlights()
" Check that we remove our highlights.
- AssertEqual
- \ [
- \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]},
- \ ],
- \ GetMatchesWithoutIDs()
+ if g:has_nvim_highlight
+ AssertEqual [], GetMatchesWithoutIDs()
+ else
+ AssertEqual
+ \ [{'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}],
+ \ GetMatchesWithoutIDs()
+ endif
Execute(Highlights should be cleared when ALE is disabled):
let g:ale_enabled = 1
@@ -291,16 +397,30 @@ Execute(Line highlights should be set when signs are disabled):
\ {'bufnr': bufnr(''), 'type': 'I', 'lnum': 3, 'col': 1},
\])
- AssertEqual
- \ [
- \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]},
- \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [2, 1, 1]},
- \ {'group': 'ALEInfo', 'priority': 10, 'pos1': [3, 1, 1]},
- \ {'group': 'aleerrorline', 'priority': 10, 'pos1': [1]},
- \ {'group': 'ALEWarningLine', 'priority': 10, 'pos1': [2]},
- \ {'group': 'ALEInfoLine', 'priority': 10, 'pos1': [3]},
- \ ],
- \ GetMatchesWithoutIDs()
+ if g:has_nvim_highlight
+ " The output is different with the newer NeoVIM highlight API.
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]},
+ \ {'group': 'ALEErrorLine', 'priority': 10, 'pos1': [1, 1, 1073741824]},
+ \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [2, 1, 1]},
+ \ {'group': 'ALEWarningLine', 'priority': 10, 'pos1': [2, 1, 1073741824]},
+ \ {'group': 'ALEInfo', 'priority': 10, 'pos1': [3, 1, 1]},
+ \ {'group': 'ALEInfoLine', 'priority': 10, 'pos1': [3, 1, 1073741824]}
+ \ ],
+ \ GetMatchesWithoutIDs()
+ else
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]},
+ \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [2, 1, 1]},
+ \ {'group': 'ALEInfo', 'priority': 10, 'pos1': [3, 1, 1]},
+ \ {'group': 'aleerrorline', 'priority': 10, 'pos1': [1]},
+ \ {'group': 'ALEWarningLine', 'priority': 10, 'pos1': [2]},
+ \ {'group': 'ALEInfoLine', 'priority': 10, 'pos1': [3]},
+ \ ],
+ \ GetMatchesWithoutIDs()
+ endif
" All of the highlights should be removed.
call ale#highlight#RemoveHighlights()