vim / vim

The official Vim repository
https://www.vim.org
Vim License
36.69k stars 5.47k forks source link

Have an option to keep original text in the quickfix window ?? #5411

Open skywind3000 opened 4 years ago

skywind3000 commented 4 years ago

Currently, quickfix/loclist window will convert matched text into a:

filename |line number| message
filename |line number| message
filename |line number| message

form, it is good for the grep output or traditional compiler outputs, but more and more modern compilers / linters trend to generate a well formatted output for better reading.

And they get hard to read after being converted by quickfix window, here is an example:

what neomake/asyncrun/dispatch.vim make out of it in the quickfix window:

quickfix1

ugh.

And this is the original output in the shell:

quickfix2

I think I made my point, the origin output in the shell is more understandable than the converted one in the quickfix.

So, can we have an option, if it is enabled, keep the original text in the quickfix window without any conversion, but highlighting is still reserved for the matched lines.

Is it reasonable request ??

vim-ml commented 4 years ago

Hi,

On Sun, Dec 29, 2019 at 11:26 PM Linwei vim-dev-github@256bit.org wrote:

Currently, quickfix/loclist window will convert matched text into a:

filename |line number| message filename |line number| message filename |line number| message

form, it is good for the grep output or traditional compiler outputs, but more and more modern compilers / linters trend to generate a well formatted output for better reading.

And they get hard to read after being converted by quickfix window, here is an example:

what neomake/asyncrun/dispatch.vim make out of it in the quickfix window:

[image: quickfix1] https://user-images.githubusercontent.com/3035071/71560564-cc5ff580-2aa6-11ea-982c-008435fd2b3c.png

ugh.

And this is the original output in the shell:

[image: quickfix2] https://user-images.githubusercontent.com/3035071/71560565-d8e44e00-2aa6-11ea-963b-e9442550ec67.png

I think I made my point, the origin output in the shell is more understandable than the converted one in the quickfix.

So, can we have an option, if it is enabled, keep the original text in the quickfix window without any conversion, but highlighting is still reserved for the matched lines.

Is it reasonable request ??

I have seen several other feature requests to customize the text displayed in the quickfix window. I am working on a patch to support this. Will shortly send a PR for this.

Shane-XB-Qian commented 4 years ago

looks i think qf basicly was for index of a error/info list. the 'conversion' you showed basicly due to qf thought it was on that purpose .. so the format changed.

probably, those plugins better put those output into a plain sp, then it would not be a issue.

skywind3000 commented 4 years ago

You mean every plugin implement their own quickfix like window ? That's totally a disaster.

Although that Vim has enough apis to allow plugins implement such thing, but plugins like neomake/asyncrun/dispatch are still using the old quickfix window, why ?

Because of standardising, quickfix is the most brilliant infrastructure in vim. Plugins using qf can collaborate with each other:

That's how errormarker works:

See, different plugins can get cooperated because there is a standard quickfix window.

Emacs is lack of such thing, every package in emacs implemented their own quickfix window with different interface and different experience. Users need to learn and accustom them one by one. Packages have no chance to cooperate with each other, just like many fragments in your editor.

So, it's totally a bad idea to let every plugin invent their own quickfix like split window in vim.

skywind3000 commented 4 years ago

Secondly, compilers are changing, for example:

test.cpp:

int main(void)
{
    int x = 0;
    x = "hello";
    return 0;
}

the output of gcc 4.2 is:

test3.cpp: In function 'int main()':
test3.cpp:4: error: invalid conversion from 'const char*' to 'int'

In deed, you can omit every unmatched lines because they are just unimportant.

Let's see the output of gcc 8.3:

test3.cpp: In function ‘int main()’:
test3.cpp:4:6: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
  x = "hello";
      ^~~~~~~

And the output of clang 8.0.1:

test3.cpp:4:6: error: assigning to 'int' from incompatible type 'const char [6]'
        x = "hello";
            ^~~~~~~
1 error generated.

When you are working with modern compilers, do you still think unmatched text is still unimportant and can be omitted ??

Quickfix is working more or less like the output window in visual studio:

output-window

It is a multi-purpose widget which can be used for:

If you still feel that every unmatched text are perplexing yourself, you can even write a function and call it after every QuickFixCmdPost event. why not ? it is a standard infrastructure.

But don't refrain qf window from other purpose and say "hey, you should only match errors". It's kind of nonsense.

I don't know why there are a lot of "should be used to" and "should not be used to" in the vim community, vim is evolving, people need to evolve too.

Shane-XB-Qian commented 4 years ago

not sure what you were arguing ... have you noticed the confusion (the why of qf format changed) in your description came from ? or you may need help from that/those plugin owner .. do a bit filter may overcome issue.

skywind3000 commented 4 years ago

In simple terms, the best choice for those plugins is to continue using quickfix instead of inventing their own qf window, but make a patch for quickfix itself to keep the original text.

andymass commented 4 years ago

Would it be better to have tree-like items in the quickfix? So the first item has line/column and message parsed but child items are untouched. You could fold away details. cnext/cprev would apply to the parent item.

skywind3000 commented 4 years ago

@andymass you mean text folding in quickfix ??

lacygoill commented 4 years ago

The second screenshot looks more readable in part because there is more noise in the first one:

Besides, it seems that these two lines have been wrongly parsed as valid entries:

expected: 2018-01-29 07:54:25.690243000 +0100
     got: 2018-01-29 07:54:25.690176000 +0100

There may be an error in the value given to the 'errorformat' option which was used to parse the output of the compiler. If you have issues setting the option, visit this site.

There are still 2 things which make the readability of the first screenshot worse than in the second one:

Both these issues can be fixed by setting the global option 'quickfixtextfunc' provided by 8.2.0869. Or by setting the attribute of the quickfix list with the same name.

This is untested, but here is a naive attempt:

set qftf=QuickFixTextFunc nowrap
fu QuickFixTextFunc(info) abort
    if a:info.quickfix
        let e = getqflist({'id': a:info.id, 'idx': a:info.idx, 'items': 1}).items[0]
    else
        let e = getloclist(0, {'id': a:info.id, 'idx': a:info.idx, 'items': 1}).items[0]
    endif
    if !e.valid
        return e.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

The part of the code which should get rid of the double bar in front of invalid entries is:

if !e.valid
    return e.text
endif

And the fields of the valid entries should be aligned via a few printf() invocations.

brammool commented 4 years ago

There is a conflict in the request: The quickfix window lists the errors/warnings one per line, so that you can navigate through them and jump to the source code where it was reported for. And the current position is indicated (position in the error list == line number). "keep original text" sounds more like a window that shows the shell output of a command. Those two completely conflict. Thus I'm not sure what you are asking for. I know that the quickfix feature (which comes from the compilers used on the Amiga, around 1988) is totally overloaded by all the features added over time. 'errorformat' is no longer a good way to specify how error messages are to be parsed (it still works, but hard to use).

Perhaps the quickfix window can be used to navigate through the errors, and another window (or popup) used to show the text before it was parsed. That's tricky, since it can be multiple lines, hard to decide where the error starts and ends, and with these "^---" indicators have to be indent-perfect (and no wrapping!). Unlikely we can make this work. Therefore showing the shell output is probably the only viable way. Then perhaps somehow relate that text to what's in the error list?

skywind3000 commented 4 years ago

@Bram, Yes, showing the shell output is probably the only viable way. But I don't need another window to display original text while using quickfix to display errors only.

What I suggest is:

Real Example

图片

Vscode has a task output window, it will display the shell output directly and errors are matched with customizable regex (like errorformat in vim). For example, if you move mouse cursor above one error line "hello.cpp:7:19" it will become a clickable link:

vscode

No need to reformat the errors, making them selectable is totally enough. Another example is the visual studio's output window which I gave before in my previous reply.

Quickfix is for errors/warnings only ??

Quickfix is evolving, some people may still want quickfix lists errors/warnings, but quickfix can do better. Other information, like building progress (which file is compiling right now) and ^-- indicators, may contain important messages which I don't want to miss them during the building progress (feeding quickfix from a job callback in realtime). Even if there is no errors/warnings, realtime messages like "compiling abcd.cpp ..." and "completed in 37 seconds without errors" are also valuable.

Why not display them in a new window rather than quickfix ??

People may ask why not create a new window to the job output directly ?? Because quickfix is a good place to display them:

some plugins can mark errors in the source by ultilizing the information in the quickfix window:

图片

some plugins can preview errors in a popup window without actually open it:

图片

So, quickfix is a good facility to display both errors and other shell outputs, no need to reinvent another similar widget. and cprev/cnext are very handy command to jump between items.

Feel disturbed by other information ??

For those people who really feel it is hard to find next error in the quickfix window (there may be some other information between errors), they can simply use cnext and cprev for navigation, or write a simple vimscript to remove unrelated text from quickfix after reading.

What about using two windows at the same time ??

Using quickfix for error listing and another window for original shell output ?? No, I don't need two windows open below my souce code, they will occupy a lot of screen space.

Are we talking about changing the quickfix behavior ??

No, you can still use quickfix the old way you like. We are talking about making quickfix possible to handle new complex jobs. And it is totally optional, which can be enabled like:

:set qftf=origin

or

:set qftf=none

The old quickfix behavior will still work unless you manually enable this.

Shane-XB-Qian commented 4 years ago

you were making a 'evolving' IDE-like vim ? :)

image // i made up this, wish was not too ugly, just manipulated the text ..

skywind3000 commented 4 years ago

@Shane-XB-Qian , what's that?

Shane-XB-Qian commented 4 years ago

i mean you don not have to make vim like IDE-like, but if really needed, you can manipulated the text as you like, that's not the impossible, the screen-cut was i made up in qf as an example. as for you wished simply put text into qf then just one set to make it worked, perhaps ok or good, but maybe needed refactor too much (or workload) & besides may had compatible issue .. // again, up to bram, but personal i suggested you can make it by you own .. besides, you can fully control it -vs- an existed legacy/classic common component.

skywind3000 commented 4 years ago

Manipulating text requires me play different tricks for each compiler. There may be multiple rules in my errorformat, I have no idea which one of them is matched and there is not enough information to restore the original text.

Shane-XB-Qian commented 4 years ago

well, looks many things looked like that, e.g vim had to face many kinds terminal emulator, front developer had to face many kinds browsers, YCM had to face many kinds langs ... you can just pick up some of you preferred, or/but you do not have to put it into qf also ..

puremourning commented 4 years ago

Here are a couple of motivating use cases that i have for this:

Agree that errorformat is a little difficult to use, but the quickfix list and the general idea/integration are a great workflow.

Therefore showing the shell output is probably the only viable way. Then perhaps somehow relate that text to what's in the error list?

Perhaps we can show the original text, while storing in the error list range from the original text that matched a specific error. We can then highlight perhaps within the original text ranges which matched an error, and map from the original text to the error list.

We would have a choice to make about how we display the current position in the error list within this "original text" buffer. An option is with the signcolum perhaps ? We also have a choice to make about which line in the "original text" buffer (which could be multiple) is associated with the specific error, but perhaps the first line is a good start. We then have a direct mapping from the error list (full errorformat matches) and the orignal text and vice-versa.

I guess this allows a sort of toggle between the two. And for the error list to continue to function as it does, but with a slightly different presentation.

Would have to try it out to see what really works I guess.

skywind3000 commented 4 years ago

@puremourning , good point, there is an alternative way rather than changing signcolumn:

demo:

[blue]hello.cpp:[red]10[/red]:[red]2[/red]:warning[/blue]: division by zero [-Wdiv-by-zero]