-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix diagnostic position when sha changes #299
Fix diagnostic position when sha changes #299
Conversation
Thanks for working on this. There is one recurring issue I've noticed. This is probably also an issue on The comment is created correctly in Gitlab, but the start line for the diagnostic is not correct. For instance, if I make a ranged comment that starts on line 7 (which is added) and spans to line 9 (in the new buffer), here's the comment's position per Gitlab: {
"body": "1",
"position": {
"base_sha": "70cf8a54aeaaa4c94802b6b641a1b32447455ca4",
"head_sha": "b2f138e2e82cdc6fcf7d55ae12b345cbc4f9a5fc",
"start_sha": "70cf8a54aeaaa4c94802b6b641a1b32447455ca4",
"new_path": "blah.js",
"old_path": "blah.js",
"position_type": "text",
"new_line": 9,
"old_line": 8,
"line_range": {
"start": {
"line_code": "766c3895fabeada8abe3a60b1b39e6baf2dd8f03_0_7",
"type": "new"
},
"end": {
"line_code": "766c3895fabeada8abe3a60b1b39e6baf2dd8f03_8_9",
"type": "old"
}
}
}
} If I had to guess, I think in this case the |
Hi @harrisoncramer, thanks for looking at this. Could you be more specific on the way the diagnostic is not correct in the case you describe? If I try to reproduce it on this PR's branch, I'm actually getting the correct diagnostic if I create a suggestion on lines 3 and 4 of the NEW buffer, ranging from an added line to an old line: new_line = 4,
old_line = 2,
range = {
["end"] = {
line_code = "669a2c84d4eb3d540cd258b34af26909f6173cef_2_4",
new_line = 0,
old_line = 0,
type = "old"
},
start = {
line_code = "669a2c84d4eb3d540cd258b34af26909f6173cef_0_3",
new_line = 0,
old_line = 0,
type = "new"
} Surprisingly, when I create the same comment in Gitlab (instead of new_line = 4,
old_line = 2,
range = {
["end"] = {
line_code = "669a2c84d4eb3d540cd258b34af26909f6173cef_2_4",
new_line = 4,
old_line = 2,
type = ""
},
start = {
line_code = "669a2c84d4eb3d540cd258b34af26909f6173cef_2_3",
new_line = 3,
old_line = 0,
type = "new"
}
}, Maybe the way ---@param d_or_n Discussion|DraftNote
---@return boolean
M.is_old_sha = function(d_or_n)
local position = M.get_first_note(d_or_n).position
local old_start_line = position.line_range ~= nil and M.parse_line_code(position.line_range.start.line_code) or nil
return position.old_line ~= nil and old_start_line ~= 0
end
---@param discussion Discussion|DraftNote
---@return boolean
M.is_new_sha = function(discussion)
return not M.is_old_sha(discussion)
end to this: ---@param d_or_n Discussion|DraftNote
---@return boolean
M.is_new_sha = function(d_or_n)
local position = M.get_first_note(d_or_n).position
local _, new_start_line = position.line_range ~= nil and M.parse_line_code(position.line_range.start.line_code) or nil, nil
return position.new_line ~= nil and new_start_line ~= 0
end
---@param discussion Discussion|DraftNote
---@return boolean
M.is_old_sha = function(discussion)
return not M.is_new_sha(discussion)
end This would, however, require some more changes, and I don't know whether this would create more problems for other diagnostics. A comprehensive test suite would be really useful for such modifications. |
Hi @harrisoncramer, I've just come back to this PR and I'd like to ask about your opinion on changing the logic of Apart from that, I've upgraded This is the same file in nvim 0.10: I'll try to figure out what's wrong with that and fix it in this PR, if you don't mind. |
Hey @jakubbortlik Let's do the issue relating to diagnostics a new MR please, I've also noticed this since switching to And yes, I agree that a comprehensive test suite would be very helpful. I'm not sure I'll ever get there, since it'd be a bit tricky to set up, we'd probably want to basically generate a hunk file that contains a bunch of changes and use it as input to these functions to validate them. Absent that, these are basically the regression checks that I've been doing to check functionality. For unranged comments, check that the following works:
For ranged comments, check that the following works:
I'm open to changing around the |
Hi Harrison. I agree that it's a good idea to fix the ranged diagnostics in a separate PR. I'd prefer to get that fixed first and only then continue work on this PR. Do you think you'll be able to do it in the near future? If not, I can try and find out what has changed in 0.10 that causes this behaviour. |
I tried looking into it for a bit this weekend and didn't see anything obvious. Go for it! I'm not sure why, but it seems like subsequent sign placements are actually removing previous ones? You might try just playing around with signs outside of the plugin entirely, this isn't an area of the editor I have much experience with so it's possible I did something dumb... |
822e499
to
e20e8d6
Compare
There was an error when the cursor was positioned right after a deleted piece of code because the hunk range was calculated incorrectly, e.g., a hunk starting at line 3, with range 2 was calculated as spanning over lines 3 trough 3+2, i.e., 3, 4, 5, wheareas it should be only 3, 4.
e20e8d6
to
59383a2
Compare
Hi @harrisoncramer, I've finally managed to track down a bug that I was experiencing and that is also present on You mentioned one more situation where the comment is not created correctly (ranged comment in new buffer, spanning from added line to unmodified line). As far as I can tell from comparing There is one remaining issue with range comments, and that is when in the new buffer when the selection starts on a modified/added line and ends on an unmodified line, the warning "Comments on unmodified lines will be placed in the old file" is displayed even if the diagnostic is in fact placed in the new buffer. I have some idea why this is happening but I'm not going to solve this in this PR that has already been open for too long, mainly because it was quite difficult and time-consuming to debug some of the tricky parts of how the diff hunks and cursor positions are analyzed. |
Using this branch right now at work and I've come across another case that is not yet solved, but I believe could be solvable (and I remember you mentioned this topic in the original issue):
I'd like to actually try and use this information to further improve diagnostic placement, but I'd prefer to leave that to a separate issue so that the current improvement gets into develop/main quicker. |
Sounds great, I'll test this out this weekend and merge it into develop once I've done so. Thank you for your hard work on this!! 💪 |
@@ -133,3 +133,17 @@ | |||
---@field commit_id string -- This will always be "" | |||
---@field line_code string | |||
---@field position NotePosition | |||
|
|||
---@class RootNode: NuiTree.Node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This annotation should actually be removed. I added it because it helped me get rid of some LSP warnings, but I didn't know the warnings were caused by a bad LSP setting. Now this annotation probably introduces more typing warnings with a properly set up LSP. I can fix this on Monday, or if you @harrisoncramer would like to merge the PR earlier, than please remove the annotation yourself.
This PR is an attempt to improve diagnostic placement and
jump_to_reviewer
behaviour reported in #158.It introduces the following changes:
jump_to_reviewer
is calculated with a common function, reducing the potential for incorrect jumpsfirst_note.position.new_line
orfirst_note.position.old_line
, rather than theline_code
- in my experience, this tends to be the most accurate source of information about where to place diagnostics, see example below. The information in theline_code
s is used to calculate the length of the diagnostic range, though.old_line
only is not always reliable, I've come across notes that had a non-nilold_line
, but still should be placed in the NEW buffer, since the line code forrange.start
looked something like this:"a34a68046a50849178410fce4af6182a98526bfc_0_94"
, -> the start of the diagnostic was not set (was0
) and the code that calculated the diagnostic positionlnum = new_start_line - 1
produced a negative value, which caused an error.I've been using this branch for some time and it looks like it improves the placement of many diagnostics, but it still does not solve all the problems. E.g., diagnostics are still misplaced for code that has been moved to a different file or for files that have been heavily modified. The good thing is, that this PR does not seem to produce worse results than the previous solution.
For the cases when diagnostics are still misplaced, I'd suggest to implement a feature that would open a new
DiffviewFileHistory
and select the revision on which the original note was made. Then the user will be free to navigate to newer versions of the file and easily see what changed so that the note placement is out of date. I'm going to open a new feature request for this.Example of diagnostics positions
In this example from a discussions tree node, the correct position is the top
new_line
, all the information inrange
(the["end"].new_line
and both line numbers in["end"].line_code
are outdated: