From 41e12fd64048c6f9c1f9b9567b22bdc3dad459d3 Mon Sep 17 00:00:00 2001 From: David le Blanc Date: Fri, 31 Mar 2023 12:50:48 +1100 Subject: [PATCH] Added column alignment for errors (#4473) --- autoload/ale/virtualtext.vim | 51 +++++++++++++++++++++++++++++++++++- doc/ale.txt | 34 ++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/autoload/ale/virtualtext.vim b/autoload/ale/virtualtext.vim index 4897154b..72bc8e6f 100644 --- a/autoload/ale/virtualtext.vim +++ b/autoload/ale/virtualtext.vim @@ -28,6 +28,11 @@ let g:ale_virtualtext_prefix = " Controls the milliseconds delay before showing a message. let g:ale_virtualtext_delay = get(g:, 'ale_virtualtext_delay', 10) +" Controls the positioning of virtualtext +let g:ale_virtualtext_column = get(g:, 'ale_virtualtext_column', 0) +let g:ale_virtualtext_maxcolumn = get(g:, 'ale_virtualtext_maxcolumn', 0) +let g:ale_virtualtext_single = get(g:,'ale_virtualtext_single',0) + let s:cursor_timer = get(s:, 'cursor_timer', -1) let s:last_pos = get(s:, 'last_pos', [0, 0, 0]) let s:hl_list = get(s:, 'hl_list', []) @@ -119,6 +124,35 @@ function! ale#virtualtext#GetGroup(item) abort return 'ALEVirtualTextInfo' endfunction +function! ale#virtualtext#GetColumnPadding(buffer, line) abort + let l:mincol = ale#Var(a:buffer, 'virtualtext_column') + let l:maxcol = ale#Var(a:buffer, 'virtualtext_maxcolumn') + let l:win = bufwinnr(a:buffer) + + if l:mincol[len(l:mincol)-1] is# '%' + let l:mincol = (winwidth(l:win) * l:mincol) / 100 + endif + + if l:maxcol[len(l:maxcol)-1] is# '%' + let l:maxcol = (winwidth(l:win) * l:maxcol) / 100 + endif + + " Calculate padding for virtualtext alignment + if l:mincol > 0 || l:maxcol > 0 + let l:line_width = strdisplaywidth(getline(a:line)) + + if l:line_width < l:mincol + return l:mincol - l:line_width + elseif l:maxcol > 0 && l:line_width >= l:maxcol + " Stop processing if virtualtext would start beyond maxcol + return -1 + endif + endif + + " no padding. + return 0 +endfunction + function! ale#virtualtext#ShowMessage(buffer, item) abort if !s:has_virt_text || !bufexists(str2nr(a:buffer)) return @@ -133,10 +167,16 @@ function! ale#virtualtext#ShowMessage(buffer, item) abort let l:prefix = ale#GetLocItemMessage(a:item, l:prefix) let l:prefix = substitute(l:prefix, '\V%comment%', '\=l:comment', 'g') let l:msg = l:prefix . substitute(a:item.text, '\n', ' ', 'g') + let l:col_pad = ale#virtualtext#GetColumnPadding(a:buffer, l:line) " Store the last message we're going to set so we can read it in tests. let s:last_message = l:msg + " Discard virtualtext if padding is negative. + if l:col_pad < 0 + return + endif + if has('nvim') call nvim_buf_set_virtual_text( \ a:buffer, @@ -174,6 +214,7 @@ function! ale#virtualtext#ShowMessage(buffer, item) abort \ 'type': l:hl_group, \ 'text': ' ' . l:msg, \ 'bufnr': a:buffer, + \ 'text_padding_left': l:col_pad, \}) endif endfunction @@ -239,9 +280,17 @@ function! ale#virtualtext#SetTexts(buffer, loclist) abort call ale#virtualtext#Clear(a:buffer) + let l:filter = ale#Var(a:buffer,'virtualtext_single') + let l:seen = {} + for l:item in a:loclist if l:item.bufnr == a:buffer - call ale#virtualtext#ShowMessage(a:buffer, l:item) + let l:line = max([1, l:item.lnum]) + + if !has_key(l:seen,l:line) || l:filter == 0 + call ale#virtualtext#ShowMessage(a:buffer, l:item) + let l:seen[l:line] = 1 + endif endif endfor endfunction diff --git a/doc/ale.txt b/doc/ale.txt index e7d9f9be..f55e73bc 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2367,6 +2367,40 @@ g:ale_virtualtext_prefix *g:ale_virtualtext_prefix* pulled from |&commentstring|, ALE will default to `'#'`. +g:ale_virtualtext_column *g:ale_virtualtext_column* + *b:ale_virtualtext_column* +g:ale_virtualtext_maxcolumn *g:ale_virtualtext_maxcolumn* + *b:ale_virtualtext_maxcolumn* + Type: |String| or |Number| + Default: `0` + + Virtualtext column range, from `column` to `maxcolumn`. If a line is + `column` or less characters long, the virtualtext message is shifted right + to `column`. + + Where the line is greater than `column` characters long, but less than + `maxcolumn`, the virtualtext message is placed at the end of the line. + + Where the line is greater than `maxcolumn` the virtualtext message is + omitted. + + A |Number| greater than `0` is used as the fixed column position, however + a |String| ending in `%` represents a percentage of the window width. + When `column` is set to zero, column positioning is disabled, when `maxcolumn` + is set to zero, no maximum line length is enforced. + +g:ale_virtualtext_single *g:ale_virtualtext_single* + *b:ale_virtualtext_single* + Type: |Number| + Default: `0` + + Enable or disable concatenation of multiple virtualtext messages on a single + line. By default, if a line has multiple errors or warnings, each will be + appended in turn. + + With `single` set to a non-zero value, only the first message appears. + (No attempt is made to prefer message types such as errors over warnings) + g:ale_virtualenv_dir_names *g:ale_virtualenv_dir_names* *b:ale_virtualenv_dir_names*