3535--- @param linnr number
3636--- @param hunk Hunk
3737--- @param all_diff_output table
38+ --- @return boolean
3839local line_was_removed = function (linnr , hunk , all_diff_output )
3940 for matching_line_index , line in ipairs (all_diff_output ) do
4041 local found_hunk = M .parse_possible_hunk_headers (line )
4142 if found_hunk ~= nil and vim .deep_equal (found_hunk , hunk ) then
4243 -- We found a matching hunk, now we need to iterate over the lines from the raw diff output
4344 -- at that hunk until we reach the line we are looking for. When the indexes match we check
4445 -- to see if that line is deleted or not.
45- for hunk_line_index = found_hunk .old_line , hunk .old_line + hunk .old_range - 1 , 1 do
46+ for hunk_line_index = found_hunk .old_line , hunk .old_line + hunk .old_range , 1 do
4647 local line_content = all_diff_output [matching_line_index + 1 ]
4748 if hunk_line_index == linnr then
4849 if string.match (line_content , " ^%-" ) then
49- return " deleted "
50+ return true
5051 end
5152 end
5253 end
5354 end
5455 end
56+ return false
5557end
5658
5759--- @param linnr number
5860--- @param hunk Hunk
5961--- @param all_diff_output table
62+ --- @return boolean
6063local line_was_added = function (linnr , hunk , all_diff_output )
6164 for matching_line_index , line in ipairs (all_diff_output ) do
6265 local found_hunk = M .parse_possible_hunk_headers (line )
@@ -71,13 +74,14 @@ local line_was_added = function(linnr, hunk, all_diff_output)
7174 local line_content = all_diff_output [hunk_line_index ]
7275 if (found_hunk .new_line + i ) == linnr then
7376 if string.match (line_content , " ^%+" ) then
74- return " added "
77+ return true
7578 end
7679 end
7780 i = i + 1
7881 end
7982 end
8083 end
84+ return false
8185end
8286
8387--- Parse git diff hunks.
@@ -173,63 +177,58 @@ local count_changes = function(lines)
173177 return total
174178end
175179
180+ --- @param new_line number | nil
181+ --- @param hunks Hunk[]
182+ --- @param all_diff_output table
183+ --- @return string | nil
184+ local function get_modification_type_from_new_sha (new_line , hunks , all_diff_output )
185+ if new_line == nil then
186+ return nil
187+ end
188+ return List .new (hunks ):find (function (hunk )
189+ local new_line_end = hunk .new_line + hunk .new_range
190+ local in_new_range = new_line >= hunk .new_line and new_line <= new_line_end
191+ local is_range_zero = hunk .new_range == 0 and hunk .old_range == 0
192+ return in_new_range and (is_range_zero or line_was_added (new_line , hunk , all_diff_output ))
193+ end ) and " added" or " bad_file_unmodified"
194+ end
195+
196+ --- @param old_line number | nil
197+ --- @param new_line number | nil
198+ --- @param hunks Hunk[]
199+ --- @param all_diff_output table
200+ --- @return string | nil
201+ local function get_modification_type_from_old_sha (old_line , new_line , hunks , all_diff_output )
202+ if old_line == nil then
203+ return nil
204+ end
205+
206+ return List .new (hunks ):find (function (hunk )
207+ local old_line_end = hunk .old_line + hunk .old_range
208+ local new_line_end = hunk .new_line + hunk .new_range
209+ local in_old_range = old_line >= hunk .old_line and old_line <= old_line_end
210+ local in_new_range = old_line >= hunk .new_line and new_line <= new_line_end
211+ return (in_old_range or in_new_range ) and line_was_removed (old_line , hunk , all_diff_output )
212+ end ) and " deleted" or " unmodified"
213+ end
214+
176215--- Returns whether the comment is on a deleted line, added line, or unmodified line.
177216--- This is in order to build the payload for Gitlab correctly by setting the old line and new line.
178217--- @param old_line number | nil
179218--- @param new_line number | nil
180219--- @param current_file string
220+ --- @param is_current_sha boolean
181221--- @return string | nil
182- function M .get_modification_type (old_line , new_line , current_file )
222+ function M .get_modification_type (old_line , new_line , current_file , is_current_sha )
183223 local hunk_and_diff_data = parse_hunks_and_diff (current_file , state .INFO .target_branch )
184224 if hunk_and_diff_data .hunks == nil then
185225 return
186226 end
187227
188228 local hunks = hunk_and_diff_data .hunks
189229 local all_diff_output = hunk_and_diff_data .all_diff_output
190-
191- local is_current_sha = require (" gitlab.reviewer" ).is_current_sha ()
192-
193- for _ , hunk in ipairs (hunks ) do
194- local old_line_end = hunk .old_line + hunk .old_range
195- local new_line_end = hunk .new_line + hunk .new_range
196-
197- if is_current_sha then
198- -- If it is a single line change and neither hunk has a range, then it's added
199- if new_line >= hunk .new_line and new_line <= new_line_end then
200- if hunk .new_range == 0 and hunk .old_range == 0 then
201- return " added"
202- end
203- -- If leaving a comment on the new window, we may be commenting on an added line
204- -- or on an unmodified line. To tell, we have to check whether the line itself is
205- -- prefixed with "+" and only return "added" if it is.
206- if line_was_added (new_line , hunk , all_diff_output ) then
207- return " added"
208- end
209- end
210- else
211- -- It's a deletion if it's in the range of the hunks and the new
212- -- range is zero, since that is only a deletion hunk, or if we find
213- -- a match in another hunk with a range, and the corresponding line is prefixed
214- -- with a "-" only. If it is, then it's a deletion.
215- if old_line >= hunk .old_line and old_line <= old_line_end and hunk .old_range == 0 then
216- return " deleted"
217- end
218- if
219- (old_line >= hunk .old_line and old_line <= old_line_end )
220- or (old_line >= hunk .new_line and new_line <= new_line_end )
221- then
222- if line_was_removed (old_line , hunk , all_diff_output ) then
223- return " deleted"
224- end
225- end
226- end
227- end
228-
229- -- If we can't find the line, this means the user is either trying to leave
230- -- a comment on an unchanged line in the new or old file SHA. This is only
231- -- allowed in the old file
232- return is_current_sha and " bad_file_unmodified" or " unmodified"
230+ return is_current_sha and get_modification_type_from_new_sha (new_line , hunks , all_diff_output )
231+ or get_modification_type_from_old_sha (old_line , new_line , hunks , all_diff_output )
233232end
234233
235234--- Returns the matching line number of a line in the new/old version of the file compared to the current SHA.
0 commit comments