From f92bbab8cf22becfaf3188474afb10245b489843 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 20 May 2017 23:32:41 +0100 Subject: [PATCH] #149 - Support Info, style error, and style warning types for problems for signs --- autoload/ale.vim | 11 ++++++ autoload/ale/engine.vim | 4 ++ autoload/ale/sign.vim | 54 ++++++++++++++++++++++++--- doc/ale.txt | 57 +++++++++++++++++++++++------ plugin/ale.vim | 9 +++-- test/sign/test_sign_placement.vader | 32 ++++++++++++++++ test/test_loclist_corrections.vader | 21 +++++++++++ 7 files changed, 169 insertions(+), 19 deletions(-) diff --git a/autoload/ale.vim b/autoload/ale.vim index ca75577..d8db3bf 100644 --- a/autoload/ale.vim +++ b/autoload/ale.vim @@ -124,6 +124,17 @@ function! ale#Var(buffer, variable_name) abort return getbufvar(str2nr(a:buffer), l:full_name, g:[l:full_name]) endfunction +" Initialize a variable with a default value, if it isn't already set. +" +" Every variable name will be prefixed with 'ale_'. +function! ale#Set(variable_name, default) abort + let l:full_name = 'ale_' . a:variable_name + let l:value = get(g:, l:full_name, a:default) + let g:[l:full_name] = l:value + + return l:value +endfunction + " Escape a string suitably for each platform. " shellescape does not work on Windows. function! ale#Escape(str) abort diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index e13562a..f4f5c1c 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -293,6 +293,10 @@ function! ale#engine#FixLocList(buffer, linter, loclist) abort let l:item.end_col = str2nr(l:old_item.end_col) endif + if has_key(l:old_item, 'sub_type') + let l:item.sub_type = l:old_item.sub_type + endif + if l:item.lnum == 0 " When errors appear at line 0, put them at line 1 instead. let l:item.lnum = 1 diff --git a/autoload/ale/sign.vim b/autoload/ale/sign.vim index 0e0250b..f16153f 100644 --- a/autoload/ale/sign.vim +++ b/autoload/ale/sign.vim @@ -8,15 +8,33 @@ if !hlexists('ALEErrorSign') highlight link ALEErrorSign error endif +if !hlexists('ALEStyleErrorSign') + highlight link ALEStyleErrorSign ALEErrorSign +endif + if !hlexists('ALEWarningSign') highlight link ALEWarningSign todo endif +if !hlexists('ALEStyleWarningSign') + highlight link ALEStyleWarningSign ALEWarningSign +endif + +if !hlexists('ALEInfoSign') + highlight link ALEInfoSign ALEWarningSign +endif + " Signs show up on the left for error markers. execute 'sign define ALEErrorSign text=' . g:ale_sign_error \ . ' texthl=ALEErrorSign linehl=ALEErrorLine' +execute 'sign define ALEStyleErrorSign text=' . g:ale_sign_style_error +\ . ' texthl=ALEStyleErrorSign linehl=ALEStyleErrorSign' execute 'sign define ALEWarningSign text=' . g:ale_sign_warning \ . ' texthl=ALEWarningSign linehl=ALEWarningLine' +execute 'sign define ALEStyleWarningSign text=' . g:ale_sign_style_warning +\ . ' texthl=ALEStyleWarningSign linehl=ALEStyleWarningSign' +execute 'sign define ALEInfoSign text=' . g:ale_sign_info +\ . ' texthl=ALEInfoSign linehl=ALEInfoLine' sign define ALEDummySign " Read sign data for a buffer to a list of lines. @@ -36,7 +54,7 @@ function! ale#sign#ParseSigns(line_list) abort " 行=1 識別子=1000001 名前=ALEWarningSign " línea=12 id=1000001 nombre=ALEWarningSign " riga=1 id=1000001, nome=ALEWarningSign - let l:pattern = '^.*=\(\d\+\).*=\(\d\+\).*=ALE\(Error\|Warning\|Dummy\)Sign' + let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)' let l:result = [] for l:line in a:line_list @@ -46,7 +64,7 @@ function! ale#sign#ParseSigns(line_list) abort call add(l:result, [ \ str2nr(l:match[1]), \ str2nr(l:match[2]), - \ 'ALE' . l:match[3] . 'Sign', + \ l:match[3], \]) endif endfor @@ -108,14 +126,40 @@ function! s:SetDummySignIfNeeded(buffer, current_sign_list, new_signs) abort return l:is_dummy_sign_set endfunction +function! ale#sign#GetSignType(sublist) abort + let l:highest_level = 100 + + for l:item in a:sublist + let l:level = (l:item.type ==# 'I' ? 2 : l:item.type ==# 'W') + + if get(l:item, 'sub_type', '') ==# 'style' + let l:level += 10 + endif + + if l:level < l:highest_level + let l:highest_level = l:level + endif + endfor + + if l:highest_level == 10 + return 'ALEStyleErrorSign' + elseif l:highest_level == 11 + return 'ALEStyleWarningSign' + elseif l:highest_level == 2 + return 'ALEInfoSign' + elseif l:highest_level == 1 + return 'ALEWarningSign' + endif + + return 'ALEErrorSign' +endfunction + function! s:PlaceNewSigns(buffer, grouped_items) abort " Add the new signs, for l:index in range(0, len(a:grouped_items) - 1) let l:sign_id = l:index + g:ale_sign_offset + 1 let l:sublist = a:grouped_items[l:index] - let l:type = !empty(filter(copy(l:sublist), 'v:val.type ==# ''E''')) - \ ? 'ALEErrorSign' - \ : 'ALEWarningSign' + let l:type = ale#sign#GetSignType(a:grouped_items[l:index]) " Save the sign IDs we are setting back on our loclist objects. " These IDs will be used to preserve items which are set many times. diff --git a/doc/ale.txt b/doc/ale.txt index f88fbbc..3331ba2 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -539,12 +539,26 @@ g:ale_set_signs *g:ale_set_signs* Default: `has('signs')` When this option is set to `1`, the |sign| column will be populated with - signs marking where errors and warnings appear in the file. The - `ALEErrorSign` and `ALEWarningSign` highlight groups will be used to provide - highlighting for the signs. The text used for signs can be customised with - the |g:ale_sign_error| and |g:ale_sign_warning| options. The `ALEErrorSign` - and `ALEWarningLine` highlight groups will be used to provide highlighting - for the lines that the signs reside on. + signs marking where problems appear in the file. + + ALE will use the following highlight groups for problems: + + `ALEErrorSign` - Items with `'type': 'E'` + `ALEWarningSign` - Items with `'type': 'W'` + `ALEInfoSign` - Items with `'type': 'I'` + `ALEStyleErrorSign` - Items with `'type': 'E'` and `'sub_type': 'style'` + `ALEStyleWarningSign` - Items with `'type': 'W'` and `'sub_type': 'style'` + + The markers for the highlights can be customized with the following options: + + |g:ale_sign_error| + |g:ale_sign_warning| + |g:ale_sign_info| + |g:ale_sign_style_error| + |g:ale_sign_style_warning| + + When multiple problems exist on the same line, the signs will take + precedence in the order above, from highest to lowest. g:ale_sign_column_always *g:ale_sign_column_always* @@ -563,9 +577,31 @@ g:ale_sign_error *g:ale_sign_error* Type: |String| Default: `'>>'` - This string can be changed to change the characters used for the sign gutter - for lines which at least one error on them. Lines with both errors and - warnings on them will show the error marker, as errors take precedence. + The sign for errors in the sign gutter. + + +g:ale_sign_info *g:ale_sign_info* + + Type: |String| + Default: `g:ale_sign_warning` + + The sign for "info" markers in the sign gutter. + + +g:ale_sign_style_error *g:ale_sign_style_error* + + Type: |String| + Default: `g:ale_sign_error` + + The sign for style errors in the sign gutter. + + +g:ale_sign_style_warning *g:ale_sign_style_warning* + + Type: |String| + Default: `g:ale_sign_warning` + + The sign for style warnings in the sign gutter. g:ale_sign_offset *g:ale_sign_offset* @@ -587,8 +623,7 @@ g:ale_sign_warning *g:ale_sign_warning* Type: |String| Default: `'--'` - This string can be changed to change the characters used for the sign gutter - for lines which at least one warning on them. + The sign for warnings in the sign gutter. g:ale_statusline_format *g:ale_statusline_format* diff --git a/plugin/ale.vim b/plugin/ale.vim index a1a8666..92c1562 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -111,9 +111,12 @@ let g:ale_set_signs = get(g:, 'ale_set_signs', has('signs')) " This flag can be set to 0 to disable setting error highlights. let g:ale_set_highlights = get(g:, 'ale_set_highlights', has('syntax')) -" These variables dicatate what sign is used to indicate errors and warnings. -let g:ale_sign_error = get(g:, 'ale_sign_error', '>>') -let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--') +" These variables dictate what sign is used to indicate errors and warnings. +call ale#Set('sign_error', '>>') +call ale#Set('sign_style_error', g:ale_sign_error) +call ale#Set('sign_warning', '--') +call ale#Set('sign_style_warning', g:ale_sign_warning) +call ale#Set('sign_info', g:ale_sign_warning) " This variable sets an offset which can be set for sign IDs. " This ID can be changed depending on what IDs are set for other plugins. diff --git a/test/sign/test_sign_placement.vader b/test/sign/test_sign_placement.vader index 707e2ce..f8e926b 100644 --- a/test/sign/test_sign_placement.vader +++ b/test/sign/test_sign_placement.vader @@ -71,6 +71,38 @@ After: call ale#linter#Reset() sign unplace * +Execute(ale#sign#GetSignType should return the right sign types): + AssertEqual 'ALEErrorSign', ale#sign#GetSignType([{'type': 'E'}]) + AssertEqual 'ALEStyleErrorSign', ale#sign#GetSignType([{'type': 'E', 'sub_type': 'style'}]) + AssertEqual 'ALEWarningSign', ale#sign#GetSignType([{'type': 'W'}]) + AssertEqual 'ALEStyleWarningSign', ale#sign#GetSignType([{'type': 'W', 'sub_type': 'style'}]) + AssertEqual 'ALEInfoSign', ale#sign#GetSignType([{'type': 'I'}]) + AssertEqual 'ALEErrorSign', ale#sign#GetSignType([ + \ {'type': 'E'}, + \ {'type': 'W'}, + \ {'type': 'I'}, + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEWarningSign', ale#sign#GetSignType([ + \ {'type': 'W'}, + \ {'type': 'I'}, + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEInfoSign', ale#sign#GetSignType([ + \ {'type': 'I'}, + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEStyleErrorSign', ale#sign#GetSignType([ + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEStyleWarningSign', ale#sign#GetSignType([ + \ {'type': 'W', 'sub_type': 'style'}, + \]) + Given testft(A file with warnings/errors): foo bar diff --git a/test/test_loclist_corrections.vader b/test/test_loclist_corrections.vader index 8e01dfb..f424424 100644 --- a/test/test_loclist_corrections.vader +++ b/test/test_loclist_corrections.vader @@ -164,3 +164,24 @@ Execute(FixLocList should pass on col_length values): \ {'text': 'a', 'lnum': '010', 'col': '011', 'end_col': 12}, \ ], \ ) + +Execute(FixLocList should allow subtypes to be set): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'sub_type': 'style', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ {'name': 'foobar'}, + \ [{'text': 'a', 'lnum': 11, 'sub_type': 'style'}], + \ )