This is my naive attempt at solving #1136. It works for me (not heavily tested yet), but I’m not sure if it’s a good idea. I would appreciate any feedback.
Geany’s message window is sort of detached from the editor. In general, it’s just lines of text that are not parsed or associated with the files in question until the user wants to navigate to one of them (although there are some exceptions).
Constrained by this design, I bolted on a cache of line number shifts. Actually two caches: one for the messages tab (`line_shifts_msg`) and one for the compiler tab (`line_shifts_compiler`). A cache is cleared when the user initiates a search/build (`msgwindow_clear_tab`), and then updated whenever the user adds/deletes lines in *any* open file (`SCN_MODIFIED` with a non-zero `linesAdded`), as long as *any* messages/errors are present. A cache is a hash table where keys are filenames and values are sequences of “at line, lines added” pairs (`LineShift`).
This of course means some overhead on mundane editing operations. Line numbers are requested from Scintilla, filename hashes are computed, arrays may need to be resized. Some of this overhead could be optimized out, but I’m not sure it’s worth it.
Also, this approach doesn’t handle undo very well. If there’s a compiler error on line 3, and I delete that entire line, and then undo the deletion, navigating to that error will now bring me to line 2 instead of 3, because the undo is understood as inserting an unrelated new line.
A possibly cleaner and/or more efficient approach might be to rely on Scintilla’s features such as line markers or indicators. That would probably require some revamp of the message window: lines would have to be parsed eagerly and associated with those Scintilla features as long as the corresponding file is open. I haven’t tried that approach.
You can view, comment on, or merge this pull request online at:
https://github.com/geany/geany/pull/1481
-- Commit Summary --
* Track changes to line numbers for messages and compiler errors
-- File Changes --
M src/build.c (2) M src/editor.c (26) M src/msgwindow.c (130) M src/msgwindow.h (4) M src/search.c (4)
-- Patch Links --
https://github.com/geany/geany/pull/1481.patch https://github.com/geany/geany/pull/1481.diff
@vfaronov pushed 1 commit.
ef3702c Forget line shifts in message window on document (re)load
I guess it depends on the language you are using and how it works, but for me (in C++) after the first few errors too many are consequential errors (things that are only wrong because of a previous error). So going beyond the first few errors is unproductive anyway, better to re-compile and see if I have fixed the first few and then attack the next. So I don't accumulate big line changes. Also languages like Python only give you one error at a time.
And I find most of my errors are ytpos so fixing them doesn't change the lines at all.
So I have never felt the need for this, and I fear its likely to add significant overhead to all users editing but only be useful to a few, which is not a good outcome. Also it is likely to have many tricky corner cases.
So my 2c would be "not a good idea" for the reasons above, but YMMV.
@elextr In my experience, it is not so in Python. Firstly, there’s Find in Files, which is very important in refactoring — probably more so than in C++, because you can’t just break things and expect the compiler to point out the places to fix. Secondly, compiler errors usually don’t come from actually running the program, but rather from static analysis tools such as Pylint and Mypy. The problems they report are often independent from each other.
However, I understand your point.
Would your opinion change if I went the indicators or line markers route instead? In that case, there would be little to no overhead during editing, because Scintilla would be keeping track of changes for us. (In fact, of course, Geany already marks errors with indicators — just not in a way that is immediately reusable for this purpose.)
@vfaronov I admit my Python is mostly small changes to a large application, or test harnesses for the C++. So I don't use much in the way of Python-Ninja tools :)
I think Scintilla has a way of adding per-line data, maybe that will help, though it may be only for lexers, not sure.
Certainly if the change is simple and the overhead is small then its a more attractive change.
Also corner case questions, what do you do if the line the message references is deleted, or combined with another line or moved to a totally different place in the file?
Certainly if the change is simple and the overhead is small then its a more attractive change.
No, unfortunately, that change would be more complex, although its runtime overhead would be smaller.
Given the lack of interest in this issue, it does seem that brittle or complex solutions are not worth it. And I don’t have a robust and simple solution. So I’m withdrawing this PR for now.
I will still be running with this change, so in case anybody’s interested, you can find it [on my master](https://github.com/geany/geany/compare/master...vfaronov:master).
Closed #1481.
github-comments@lists.geany.org