diff --git a/autoload/ale.vim b/autoload/ale.vim index 15fb53d..f6c06cf 100644 --- a/autoload/ale.vim +++ b/autoload/ale.vim @@ -257,3 +257,31 @@ function! ale#Escape(str) abort return shellescape (a:str) endfunction + +" Get the loclist item message according to a given format string. +" +" See `:help g:ale_loclist_msg_format` and `:help g:ale_echo_msg_format` +function! ale#GetLocItemMessage(item, format_string) abort + let l:msg = a:format_string + let l:severity = g:ale_echo_msg_warning_str + let l:code = get(a:item, 'code', '') + let l:type = get(a:item, 'type', 'E') + let l:linter_name = get(a:item, 'linter_name', '') + let l:code_repl = !empty(l:code) ? '\=submatch(1) . l:code . submatch(2)' : '' + + if l:type is# 'E' + let l:severity = g:ale_echo_msg_error_str + elseif l:type is# 'I' + let l:severity = g:ale_echo_msg_info_str + endif + + " Replace special markers with certain information. + " \=l:variable is used to avoid escaping issues. + let l:msg = substitute(l:msg, '\V%severity%', '\=l:severity', 'g') + let l:msg = substitute(l:msg, '\V%linter%', '\=l:linter_name', 'g') + let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g') + " Replace %s with the text. + let l:msg = substitute(l:msg, '\V%s', '\=a:item.text', 'g') + + return l:msg +endfunction diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim index 7b84862..1980c19 100644 --- a/autoload/ale/cursor.vim +++ b/autoload/ale/cursor.vim @@ -4,30 +4,6 @@ let s:cursor_timer = -1 let s:last_pos = [0, 0, 0] -" Return a formatted message according to g:ale_echo_msg_format variable -function! s:GetMessage(item) abort - let l:msg = g:ale_echo_msg_format - let l:severity = g:ale_echo_msg_warning_str - let l:code = get(a:item, 'code', '') - let l:code_repl = !empty(l:code) ? '\=submatch(1) . l:code . submatch(2)' : '' - - if a:item.type is# 'E' - let l:severity = g:ale_echo_msg_error_str - elseif a:item.type is# 'I' - let l:severity = g:ale_echo_msg_info_str - endif - - " Replace special markers with certain information. - " \=l:variable is used to avoid escaping issues. - let l:msg = substitute(l:msg, '\V%severity%', '\=l:severity', 'g') - let l:msg = substitute(l:msg, '\V%linter%', '\=a:item.linter_name', 'g') - let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g') - " Replace %s with the text. - let l:msg = substitute(l:msg, '\V%s', '\=a:item.text', 'g') - - return l:msg -endfunction - function! s:EchoWithShortMess(setting, message) abort " We need to remember the setting for shormess and reset it again. let l:shortmess_options = getbufvar('%', '&shortmess') @@ -96,7 +72,7 @@ function! s:EchoImpl() abort let [l:info, l:loc] = s:FindItemAtCursor() if !empty(l:loc) - let l:msg = s:GetMessage(l:loc) + let l:msg = ale#GetLocItemMessage(l:loc, g:ale_echo_msg_format) call ale#cursor#TruncatedEcho(l:msg) let l:info.echoed = 1 elseif get(l:info, 'echoed') diff --git a/autoload/ale/list.vim b/autoload/ale/list.vim index ecf088a..fbc71ef 100644 --- a/autoload/ale/list.vim +++ b/autoload/ale/list.vim @@ -41,13 +41,16 @@ function! s:FixList(list) abort let l:new_list = [] for l:item in a:list + let l:fixed_item = copy(l:item) + + let l:fixed_item.text = ale#GetLocItemMessage( + \ l:item, + \ g:ale_loclist_msg_format, + \) + if l:item.bufnr == -1 " If the buffer number is invalid, remove it. - let l:fixed_item = copy(l:item) call remove(l:fixed_item, 'bufnr') - else - " Don't copy the Dictionary if we do not need to. - let l:fixed_item = l:item endif call add(l:new_list, l:fixed_item) diff --git a/doc/ale.txt b/doc/ale.txt index 353c6db..2126687 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -656,6 +656,7 @@ g:ale_echo_msg_format *g:ale_echo_msg_format* The strings for `%severity%` can be configured with the following options. |g:ale_echo_msg_error_str| - Defaults to `'Error'` + |g:ale_echo_msg_info_str| - Defaults to `'Info'` |g:ale_echo_msg_warning_str| - Defaults to `'Warning'` `%code%` is replaced with the error code, and replaced with an empty string @@ -994,6 +995,17 @@ g:ale_linters *g:ale_linters* let b:ale_linters = 'all' < +g:ale_loclist_msg_format *g:ale_loclist_msg_format* + + Type: |String| + Default: `g:ale_echo_msg_format` + + This option is the same as |g:ale_echo_msg_format|, but for formatting the + message used for the loclist and the quickfix list. + + The strings for configuring `%severity%` are also used for this option. + + g:ale_max_buffer_history_size *g:ale_max_buffer_history_size* Type: |Number| diff --git a/plugin/ale.vim b/plugin/ale.vim index 26d3c43..11df520 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -149,7 +149,9 @@ let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000) let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0) " A string format for the echoed message -let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s') +call ale#Set('echo_msg_format', '%code: %%s') +" The same for the loclist. +call ale#Set('loclist_msg_format', g:ale_echo_msg_format) " Strings used for severity in the echoed message let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error') diff --git a/test/test_list_formatting.vader b/test/test_list_formatting.vader new file mode 100644 index 0000000..6b494fc --- /dev/null +++ b/test/test_list_formatting.vader @@ -0,0 +1,164 @@ +Before: + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_loclist_msg_format + Save g:ale_open_list + Save g:ale_buffer_info + Save g:ale_set_lists_synchronously + + let g:ale_set_lists_synchronously = 1 + let g:ale_loclist_msg_format = '%code: %%s' + let g:ale_open_list = 0 + let g:loclist = [] + let g:ale_buffer_info = {bufnr(''): {'loclist': g:loclist}} + + function! AddItem(data) abort + let l:item = { + \ 'bufnr': bufnr(''), + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'linter_name': 'some_linter', + \} + + call add(g:loclist, extend(l:item, a:data)) + endfunction + +After: + Restore + + unlet! g:loclist + + delfunction AddItem + + call setloclist(0, []) + call setqflist([]) + +Execute(Formatting with codes should work for the loclist): + call AddItem({'text': 'nocode'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'nocode', + \ }, + \ ], + \ getloclist(0) + + call remove(g:loclist, 0) + call AddItem({'text': 'withcode', 'code': 'E123'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'E123: withcode', + \ }, + \ ], + \ getloclist(0) + +Execute(Formatting with codes should work for the quickfix list): + let g:ale_set_loclist = 0 + let g:ale_set_quickfix = 1 + + call AddItem({'text': 'nocode'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'nocode', + \ }, + \ ], + \ getqflist() + + call remove(g:loclist, 0) + call AddItem({'text': 'withcode', 'code': 'E123'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'E123: withcode', + \ }, + \ ], + \ getqflist() + +Execute(Formatting with the linter name should work for the loclist): + let g:ale_loclist_msg_format = '(%linter%) %s' + + call AddItem({'text': 'whatever'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': '(some_linter) whatever', + \ }, + \ ], + \ getloclist(0) + +Execute(Formatting with the linter name should work for the quickfix list): + let g:ale_loclist_msg_format = '(%linter%) %s' + let g:ale_set_loclist = 0 + let g:ale_set_quickfix = 1 + + call AddItem({'text': 'whatever'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': '(some_linter) whatever', + \ }, + \ ], + \ getqflist()