[vim/vim] Format quickfix output (#4425)

126 views
Skip to first unread message

Ihor Antonov

unread,
May 24, 2019, 10:18:50 AM5/24/19
to vim/vim, Subscribed

As @justinmk suggetsted I am re-opening neovim/neovim#10056 here

I write rust with rls and often use quickfix window to find issues.

If you compare how similar "quickfix" window looks in Emacs you will notice that the output is
justified by columns, and overall is more readable.

Emacs flycheck:
emacs-flycheck

vim quickfix:
vim-quickfix

I have not found any options to format the output of the quickfix window. It would be great to have
the ability to provide printf-like format a string for quickfix item, specifying column lengths, and inlucing/excluding items like column numbers, error codes etc.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub

Tony Mechelynck

unread,
May 24, 2019, 11:08:19 AM5/24/19
to vim/vim, Subscribed

I often use quickfix commands, but I rarely use the quickfix window. I have in fact some of the following mappings for easier moving about in the quickfix list:

if exists(':map') == 2
  if has('quickfix')
    map <F2>   :cnext<CR>
    map <S-F2> :cprev<CR>
    map <F3>   :cnfile<CR>
    map <S-F3> :cpfile<CR>
    map <F4>   :cfirst<CR>
    map <S-F4> :clast<CR>
  endif
endif

Some are more useful than others so you may want to put only some of them in your vimrc.

This said, I think that what you see is due to the history of how the quickfix feature was added to Vim: the :make command and the 'errorformat' option were added first, to help Vim decode compilers' output messages and bring up the corresponding source line. Then (IIRC) :grep, :helpgrep and :vimgrep (in that order) were added to treat the grep utility as a compiler, and then to add Vim-intrinsic capabilities for searching the helpfiles, then any files, according to Vim's own regular expresion syntax.

The format of a compiler's output is of course something over which Vim has no control. In the case of the intrinsic :helpgrep and :vimgrep commands, there are pluses and minuses to what you are requesting: among the minus points, aligning the text would IIUC require two-pass handling, one pass to determine the longest string in each column and then a second pass to output the text; then the extra spaces would mean that the visible source text would be truncated earlier than now whenever the text representing the filename, line and column would be shorter than the maximum (and therefore be padded with a certain number of spaces).

Best regards,
Tony.

lacygoill

unread,
May 24, 2019, 3:53:55 PM5/24/19
to vim/vim, Subscribed

This is not what you want, but in the meantime, to make the entries aligned, I use something like this in ~/.vim/after/plugin/qf.vim:

if executable('column') && executable('sed')

    let s:ul_save = &l:ul

    setl modifiable ul=-1

    sil! exe "%!sed 's/|/\<c-a>|/1'"

    sil! exe "%!sed 's/|/\<c-a>|/2'"

    sil! exe "%!column -s '\<c-a>' -t"

    let &l:ul = s:ul_save

    unlet! s:ul_save

    setl nomodifiable nomodified

endif

It requires the $ sed and $ column utilities.

And to shorten the file paths, if you have the patch 8.0.1782, you can use the 'module' property of the quickfix list to change the text which is displayed:

call setqflist([], 'r', {'items': map(getqflist(),

    \ {i,v -> extend(v, {'module': substitute(fnamemodify(bufname(v.bufnr), ':t'), '.\{7}\zs.\+', '…', '')})})})

if executable('column') && executable('sed')

    let s:ul_save = &l:ul

    setl modifiable ul=-1

    sil! exe "%!sed 's/|/\<c-a>|/1'"

    sil! exe "%!sed 's/|/\<c-a>|/2'"

    sil! exe "%!column -s '\<c-a>' -t"

    let &l:ul = s:ul_save

    unlet! s:ul_save

    setl nomodifiable nomodified

endif


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or mute the thread.

Daniel Hahler

unread,
May 31, 2019, 10:21:32 PM5/31/19
to vim/vim, Subscribed

Just for reference: Neomake has an experimental/optional feature to re-format the quickfix/location list (via neomake#quickfix#enable()).
It applies formatting according to / based on the makers/linters that were used, and adds basic highlighting, e.g. for E\d+ from Python's flake8.
It also shortens / aligns columns, and only displays the buffer name if necessary (when multiple buffers are in the list), otherwise (and in general) the quickfix title is used.
lnum/cols and maker names are aligned.

With multiple buffers it adds the name to the first entry where it changes. When it would use a separate column for this, a lot of space would be wasted (since that's repeated information).

2019-06-01-041634_952x515_escrotum

I see that this is very specific to Neomake's use case, and especially for having a single buffer therein mostly, but just wanted to share this anyway

Daniel Hahler

unread,
May 31, 2019, 10:31:08 PM5/31/19
to vim/vim, Subscribed

One quick/good improvement would be to use fname:39:15 instead of fname|39 col 15|, which also makes it easier to copy'n'paste for other tools (that handle fname:lnum).
Although it should probably not use fname:col then, but maybe rather fname::col (for then there is no lnum, but only a column).

Yegappan Lakshmanan

unread,
Jun 1, 2019, 1:36:06 AM6/1/19
to vim_dev, reply+ACY5DGDTCUAHTQ3RXJ...@reply.github.com, vim/vim, Subscribed
Hi,

I have been thinking about implementing something along the lines of the
'statusline' option (e.g. 'qfline') for formatting the lines displayed in the 
quickfix buffer.

- Yegappan

vim-dev ML

unread,
Jun 1, 2019, 1:36:28 AM6/1/19
to vim/vim, vim-dev ML, Your activity
Hi,

I have been thinking about implementing something along the lines of the
'statusline' option (e.g. 'qfline') for formatting the lines displayed in
the
quickfix buffer.

- Yegappan

On Fri, May 31, 2019 at 7:21 PM Daniel Hahler <vim-dev...@256bit.org>
wrote:

> Just for reference: Neomake has an experimental/optional feature to
> re-format the quickfix/location list (via neomake#quickfix#enable()).
> It applies formatting according to / based on the makers/linters that were
> used, and adds basic highlighting, e.g. for E\d+ from Python's flake8.
> It also shortens / aligns columns, and only displays the buffer name if
> necessary (when multiple buffers are in the list), otherwise (and in
> general) the quickfix title is used.
> lnum/cols and maker names are aligned.
>
> With multiple buffers it adds the name to the first entry where it
> changes. When it would use a separate column for this, a lot of space would
> be wasted (since that's repeated information).
>
> [image: 2019-06-01-041634_952x515_escrotum]
> <https://user-images.githubusercontent.com/9766/58742312-1820c280-8424-11e9-95b3-66bf22731f25.png>

>
> I see that this is very specific to Neomake's use case, and especially for
> having a single buffer therein mostly, but just wanted to share this anyway
>
>
>

Christian Brabandt

unread,
Jun 3, 2019, 3:06:46 AM6/3/19
to vim/vim, vim-dev ML, Comment

isn't it possible to make use of concealing for aligning?


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Jun 15, 2019, 12:39:55 PM6/15/19
to vim_dev, reply+ACY5DGDTCUAHTQ3RXJ...@reply.github.com, vim/vim, Subscribed
Hi,


> On Fri, May 31, 2019 at 10:35 PM Yegappan Lakshmanan <yega...@gmail.com> wrote:
> Hi,
>
> I have been thinking about implementing something along the lines of
> the 'statusline' option (e.g. 'qfline') for formatting the lines
> displayed in the quickfix buffer.
>

I looked into implementing this option. Currently each line in the
quickfix buffer has three columns (filename, line/column/error type
information and error message). To align these columns, we can support
the following format for this option:

     set qfline=20,10

where, the first number specifies the width of the first column and the
second number specifies the width of the second column and the rest of
the line will be used for the third column. The values within the
columns will be right-aligned. So if a long filename is used, only the
rightmost characters in the filename will be displayed.

Any comments/suggestions on this?

I also considered supporting a more generic printf like format for this
option:

   set qfline=%20f,%10l,%10m

where the fields are optional and additional fields from the quickfix
entry can be used. I am not sure whether this level of flexibility
is needed for this option.

Thanks,
Yegappan

vim-dev ML

unread,
Jun 15, 2019, 12:40:20 PM6/15/19
to vim/vim, vim-dev ML, Your activity

Ihor Antonov

unread,
Jun 15, 2019, 2:46:59 PM6/15/19
to vim/vim, vim-dev ML, Mention

@vim-ml how can I try this option? Is this in master?


You are receiving this because you were mentioned.

Yegappan Lakshmanan

unread,
Jun 15, 2019, 2:57:24 PM6/15/19
to vim_dev, reply+ACY5DGDVCA5ZCNMOTJ...@reply.github.com, vim/vim, vim-dev ML, Mention
Hi,

On Sat, Jun 15, 2019 at 11:46 AM Ihor Antonov <vim-dev...@256bit.org> wrote:
>
> @vim-ml how can I try this option? Is this in master?
>

No. This is not yet implemented and merged. I am looking for comments
before implementing it.

- Yegappan

vim-dev ML

unread,
Jun 15, 2019, 2:57:49 PM6/15/19
to vim/vim, vim-dev ML, Your activity

George Brown

unread,
Jul 11, 2019, 10:06:56 AM7/11/19
to vim/vim, vim-dev ML, Mention

Just as an FYI there are plugins like vim-addon-qf-layout that alter the contents of the quickfix window. I use this simplified version.

This will of course throw off what Vim considers to be the expected syntax. So if you care about that you'll need to re-define qfFileName, qfSeparator, qfLineNr, and qfError accordingly.


You are receiving this because you were mentioned.

lacygoill

unread,
Jun 6, 2020, 5:57:12 PM6/6/20
to vim/vim, vim-dev ML, Mention

I think this is fixed by 8.2.0869 which provides the global option 'quickfixtextfunc', as well as a quickfix list attribute with the same name.


I had a look at the screenshot; you could get the desired result, or at least something close enough with this code:

vim -Nu NONE -S <(cat <<'EOF'

    set qftf=QuickFixTextFunc nowrap

    fu QuickFixTextFunc(info) abort

        if a:info.quickfix

            let size = getqflist({'size': 1}).size

            let e = getqflist({'id': a:info.id, 'idx': a:info.idx, 'items': 1}).items[0]

        else

            let size = getloclist(0, {'size': 1}).size

            let e = getloclist(0, {'id': a:info.id, 'idx': a:info.idx, 'items': 1}).items[0]

        endif

        if size > 1000 | return 'some text' | endif

        let fname = fnamemodify(bufname(e.bufnr), ':t')

        if strchars(fname, 1) <= 8

            let fname = printf('%8s', fname)

        else

            let fname = printf('%.7s', fname)..'…'

        endif

        let lnum = printf('%5d', e.lnum)

        let col = printf('%3d', e.col)

        return fname..'|'..lnum..' col '..col..'| '..e.text

    endfu

EOF

) +'helpg foobar' +copen


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.

Christian Brabandt

unread,
Jun 7, 2020, 3:01:34 AM6/7/20
to vim/vim, vim-dev ML, Mention

Closed #4425.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.

Christian Brabandt

unread,
Jun 7, 2020, 3:01:37 AM6/7/20
to vim/vim, vim-dev ML, Mention

closing then. Thanks.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.

Reply all
Reply to author
Forward
0 new messages