Open skywind3000 opened 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.
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.
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:
neomake
/asyncrun
/dispatch
can generate outputs in quickfixerrormarker
can retrive information from qf and set error markers for lines with compile errors.vim-preview
can preview errors in the preview window when you press a p
in the quickfix.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.
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:
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.
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.
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.
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.
@andymass you mean text folding in quickfix ??
The second screenshot looks more readable in part because there is more noise in the first one:
'number'
option in a qf filetype plugin'colorcolumn'
option in a qf filetype plugin'list'
option in a qf filetype pluginBesides, 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.
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?
@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:
set qftf=origin
to enable this feature.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:
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 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.
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.
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.
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.
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.
you were making a 'evolving' IDE-like vim ? :)
// i made up this, wish was not too ugly, just manipulated the text ..
@Shane-XB-Qian , what's that?
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.
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.
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 ..
Here are a couple of motivating use cases that i have for this:
:make
(e.g. "run the test i just edited"). Test outputs often contain detailed information about what failed, along with source/line info about the location of the failure. Again, we want to be able to jump to next/prev failure but also be able to see the elaborated output of the test to see what failed and why.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.
@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]
Currently, quickfix/loclist window will convert matched text into a:
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:
ugh.
And this is the original output in the shell:
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 ??