From 584e0bc7f25563bf4ab3ae738b78d9d13a898f94 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 13 Nov 2017 00:47:34 +0000 Subject: [PATCH] #852 Support formatting echo messages with error codes. No linters set the `code` key yet --- autoload/ale/cursor.vim | 23 ++++++++++------ doc/ale.txt | 15 +++++++--- plugin/ale.vim | 6 ++-- test/test_ale_info.vader | 2 +- test/test_cursor_warnings.vader | 49 +++++++++++++++++++++++---------- 5 files changed, 63 insertions(+), 32 deletions(-) diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim index c7c74c9..7b84862 100644 --- a/autoload/ale/cursor.vim +++ b/autoload/ale/cursor.vim @@ -5,22 +5,27 @@ 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(linter, type, text) abort +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:type is# 'E' + if a:item.type is# 'E' let l:severity = g:ale_echo_msg_error_str - elseif a:type is# 'I' + elseif a:item.type is# 'I' let l:severity = g:ale_echo_msg_info_str endif - " Replace handlers if they exist - for [l:k, l:v] in items({'linter': a:linter, 'severity': l:severity}) - let l:msg = substitute(l:msg, '\V%' . l:k . '%', l:v, '') - endfor + " 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 printf(l:msg, a:text) + return l:msg endfunction function! s:EchoWithShortMess(setting, message) abort @@ -91,7 +96,7 @@ function! s:EchoImpl() abort let [l:info, l:loc] = s:FindItemAtCursor() if !empty(l:loc) - let l:msg = s:GetMessage(l:loc.linter_name, l:loc.type, l:loc.text) + let l:msg = s:GetMessage(l:loc) call ale#cursor#TruncatedEcho(l:msg) let l:info.echoed = 1 elseif get(l:info, 'echoed') diff --git a/doc/ale.txt b/doc/ale.txt index 5638a2c..3a43685 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -643,20 +643,27 @@ g:ale_echo_msg_error_str *g:ale_echo_msg_error_str* g:ale_echo_msg_format *g:ale_echo_msg_format* Type: |String| - Default: `'%s'` + Default: `'%code: %%s'` This variable defines a message format for echoed messages. The following sequences of characters will be replaced. - `%s` - will be replaced with the text for the problem - `%linter%` - will be replaced with the name of the linter - `%severity%` - will be replaced withe severity of the problem + `%s` - replaced with the text for the problem + `%...code...% `- replaced with the error code + `%linter%` - replaced with the name of the linter + `%severity%` - replaced withe severity of the problem The strings for `%severity%` can be configured with the following options. |g:ale_echo_msg_error_str| - Defaults to `'Error'` |g:ale_echo_msg_warning_str| - Defaults to `'Warning'` + `%code%` is replaced with the error code, and replaced with an empty string + when there is no error code. Any extra characters between the percent signs + will be printed when an error code is present. For example, a message like + `(error code): message` will be printed for `'%(code): %%s'` and simply the + message will be printed when there is no code. + |g:ale_echo_cursor| needs to be set to 1 for messages to be displayed. diff --git a/plugin/ale.vim b/plugin/ale.vim index c67e1de..26d3c43 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -148,10 +148,8 @@ 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) -" String format for the echoed message -" A %s is mandatory -" It can contain 2 handlers: %linter%, %severity% -let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%s') +" A string format for the echoed message +let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s') " 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_ale_info.vader b/test/test_ale_info.vader index ceb65af..30237a3 100644 --- a/test/test_ale_info.vader +++ b/test/test_ale_info.vader @@ -21,7 +21,7 @@ Before: \ '', \ 'let g:ale_echo_cursor = 1', \ 'let g:ale_echo_msg_error_str = ''Error''', - \ 'let g:ale_echo_msg_format = ''%s''', + \ 'let g:ale_echo_msg_format = ''%code: %%s''', \ 'let g:ale_echo_msg_warning_str = ''Warning''', \ 'let g:ale_enabled = 1', \ 'let g:ale_fix_on_save = 0', diff --git a/test/test_cursor_warnings.vader b/test/test_cursor_warnings.vader index 20ccb15..dbcbe66 100644 --- a/test/test_cursor_warnings.vader +++ b/test/test_cursor_warnings.vader @@ -12,8 +12,9 @@ Before: \ 'linter_name': 'eslint', \ 'nr': -1, \ 'type': 'E', - \ 'text': 'Missing semicolon. (semi)', - \ 'detail': "Every statement should end with a semicolon\nsecond line" + \ 'code': 'semi', + \ 'text': 'Missing semicolon.', + \ 'detail': "Every statement should end with a semicolon\nsecond line", \ }, \ { \ 'lnum': 1, @@ -33,7 +34,8 @@ Before: \ 'linter_name': 'eslint', \ 'nr': -1, \ 'type': 'W', - \ 'text': 'Infix operators must be spaced. (space-infix-ops)' + \ 'code': 'space-infix-ops', + \ 'text': 'Infix operators must be spaced.', \ }, \ { \ 'lnum': 2, @@ -43,7 +45,8 @@ Before: \ 'linter_name': 'eslint', \ 'nr': -1, \ 'type': 'E', - \ 'text': 'Missing radix parameter (radix)' + \ 'code': 'radix', + \ 'text': 'Missing radix parameter', \ }, \ { \ 'lnum': 3, @@ -53,7 +56,7 @@ Before: \ 'linter_name': 'eslint', \ 'nr': -1, \ 'type': 'E', - \ 'text': 'lowercase error' + \ 'text': 'lowercase error', \ }, \ ], \ }, @@ -103,19 +106,19 @@ Execute(Messages should be shown for the correct lines): call cursor(1, 1) call ale#cursor#EchoCursorWarning() - AssertEqual 'Missing semicolon. (semi)', GetLastMessage() + AssertEqual 'semi: Missing semicolon.', GetLastMessage() Execute(Messages should be shown for earlier columns): call cursor(2, 1) call ale#cursor#EchoCursorWarning() - AssertEqual 'Infix operators must be spaced. (space-infix-ops)', GetLastMessage() + AssertEqual 'space-infix-ops: Infix operators must be spaced.', GetLastMessage() Execute(Messages should be shown for later columns): call cursor(2, 16) call ale#cursor#EchoCursorWarning() - AssertEqual 'Missing radix parameter (radix)', GetLastMessage() + AssertEqual 'radix: Missing radix parameter', GetLastMessage() Execute(The message at the cursor should be shown when linting ends): call cursor(1, 1) @@ -124,13 +127,13 @@ Execute(The message at the cursor should be shown when linting ends): \ g:ale_buffer_info[bufnr('%')].loclist, \) - AssertEqual 'Missing semicolon. (semi)', GetLastMessage() + AssertEqual 'semi: Missing semicolon.', GetLastMessage() Execute(The message at the cursor should be shown on InsertLeave): call cursor(2, 9) doautocmd InsertLeave - AssertEqual 'Infix operators must be spaced. (space-infix-ops)', GetLastMessage() + AssertEqual 'space-infix-ops: Infix operators must be spaced.', GetLastMessage() Execute(ALEDetail should print 'detail' attributes): call cursor(1, 1) @@ -148,7 +151,7 @@ Execute(ALEDetail should print regular 'text' attributes): ALEDetail redir END - AssertEqual "\nInfix operators must be spaced. (space-infix-ops)", g:output + AssertEqual "\nInfix operators must be spaced.", g:output Execute(ALEDetail should not capitlise cursor messages): call cursor(3, 1) @@ -163,7 +166,7 @@ Execute(The linter name should be formatted into the message correctly): call ale#cursor#EchoCursorWarning() AssertEqual - \ 'eslint: Infix operators must be spaced. (space-infix-ops)', + \ 'eslint: Infix operators must be spaced.', \ GetLastMessage() Execute(The severity should be formatted into the message correctly): @@ -173,15 +176,33 @@ Execute(The severity should be formatted into the message correctly): call ale#cursor#EchoCursorWarning() AssertEqual - \ 'Warning: Infix operators must be spaced. (space-infix-ops)', + \ 'Warning: Infix operators must be spaced.', \ GetLastMessage() call cursor(1, 10) call ale#cursor#EchoCursorWarning() - AssertEqual 'Error: Missing semicolon. (semi)', GetLastMessage() + AssertEqual 'Error: Missing semicolon.', GetLastMessage() call cursor(1, 14) call ale#cursor#EchoCursorWarning() AssertEqual 'Info: Some information', GetLastMessage() + +Execute(The %code% and %ifcode% should show the code and some text): + let g:ale_echo_msg_format = '%(code) %%s' + + call cursor(2, 9) + call ale#cursor#EchoCursorWarning() + + AssertEqual + \ '(space-infix-ops) Infix operators must be spaced.', + \ GetLastMessage() + +Execute(The %code% and %ifcode% should be removed when there's no code): + let g:ale_echo_msg_format = '%(code) %%s' + + call cursor(1, 14) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'Some information', GetLastMessage()