2.0.0 (#196)
This MR is a #MAJOR breaking change to the plugin. While the plugin will continue to work for users with their existing settings, they will be informed of outdated configuration (diagnostics and signs have been simplified) the next time they open the reviewer. Fix: Trim trailing slash from custom URLs Update: .github/CONTRIBUTING.md, .github/ISSUE_TEMPLATE/bug_report.md Feat: Improve discussion tree toggling (#192) Fix: Toggle modified notes (#188) Fix: Toggle discussion nodes correctly Feat: Show Help keymap in discussion tree winbar Fix: Enable toggling nodes from the note body Fix: Enable toggling resolved status from child nodes Fix: Only try to show emoji popup on note nodes Feat: Add keymap for toggling tree type Fix: Disable tree type toggling in Notes Fix Multi Line Issues (Large Refactor) (#197) Fix: Multi-line discussions. The calculation of a range for a multiline comment has been consolidated and moved into the location.lua file. This does not attempt to fix diagnostics. Refactor: It refactors the discussions code to split hunk parsing and management into a separate module Fix: Don't allow comments on modified buffers #194 by preventing comments on the reviewer when using --imply-local and when the working tree is dirty entirely. Refactor: It introduces a new List class for data aggregation, filtering, etc. Fix: It removes redundant API calls and refreshes from the discussion pane Fix: Location provider (#198) Fix: add nil check for Diffview performance issue (#199) Fix: Switch Tabs During Comment Creation (#200) Fix: Check if file is modified (#201) Fix: Off-By-One Issue in Old SHA (#202) Fix: Rebuild Diagnostics + Signs (#203) Fix: Off-By-One Issue in New SHA (#205) Fix: Reviewer Jumps to wrong location (#206) BREAKING CHANGE: Changes configuration of diagnostics and signs in the setup call.
This commit is contained in:
committed by
GitHub
parent
f6a5238d4b
commit
b5b475ce8b
223
lua/gitlab/reviewer/location.lua
Executable file
223
lua/gitlab/reviewer/location.lua
Executable file
@@ -0,0 +1,223 @@
|
||||
local u = require("gitlab.utils")
|
||||
local hunks = require("gitlab.hunks")
|
||||
local state = require("gitlab.state")
|
||||
|
||||
---@class Location
|
||||
---@field location_data LocationData
|
||||
---@field reviewer_data DiffviewInfo
|
||||
---@field run function
|
||||
---@field build_location_data function
|
||||
|
||||
---@class ReviewerLineInfo
|
||||
---@field old_line integer|nil
|
||||
---@field new_line integer|nil
|
||||
---@field type "new"|"old"
|
||||
|
||||
---@class ReviewerRangeInfo
|
||||
---@field start ReviewerLineInfo
|
||||
---@field end ReviewerLineInfo
|
||||
|
||||
local Location = {}
|
||||
Location.__index = Location
|
||||
---@param reviewer_data DiffviewInfo
|
||||
---@param visual_range LineRange | nil
|
||||
---@return Location
|
||||
function Location.new(reviewer_data, visual_range)
|
||||
local location = {}
|
||||
local instance = setmetatable(location, Location)
|
||||
instance.reviewer_data = reviewer_data
|
||||
instance.visual_range = visual_range
|
||||
instance.base_sha = state.INFO.diff_refs.base_sha
|
||||
instance.head_sha = state.INFO.diff_refs.head_sha
|
||||
return instance
|
||||
end
|
||||
|
||||
---Takes in information about the current changes, such as the file name, modification type of the diff, and the line numbers
|
||||
---and builds the appropriate payload when creating a comment.
|
||||
function Location:build_location_data()
|
||||
---@type DiffviewInfo
|
||||
local reviewer_data = self.reviewer_data
|
||||
---@type LineRange | nil
|
||||
local visual_range = self.visual_range
|
||||
|
||||
---@type LocationData
|
||||
local location_data = {
|
||||
old_line = nil,
|
||||
new_line = nil,
|
||||
line_range = nil,
|
||||
}
|
||||
|
||||
-- Comment on new line: Include only new_line in payload.
|
||||
-- Comment on deleted line: Include only old_line in payload.
|
||||
-- The line was not found in any hunks, send both lines.
|
||||
if reviewer_data.modification_type == "added" then
|
||||
location_data.old_line = nil
|
||||
location_data.new_line = reviewer_data.new_line_from_buf
|
||||
elseif reviewer_data.modification_type == "deleted" then
|
||||
location_data.old_line = reviewer_data.old_line_from_buf
|
||||
location_data.new_line = nil
|
||||
elseif
|
||||
reviewer_data.modification_type == "unmodified" or reviewer_data.modification_type == "bad_file_unmodified"
|
||||
then
|
||||
location_data.old_line = reviewer_data.old_line_from_buf
|
||||
location_data.new_line = reviewer_data.new_line_from_buf
|
||||
end
|
||||
|
||||
self.location_data = location_data
|
||||
if visual_range == nil then
|
||||
return
|
||||
else
|
||||
self.location_data.line_range = {
|
||||
start = {},
|
||||
["end"] = {},
|
||||
}
|
||||
end
|
||||
|
||||
self:set_start_range(visual_range)
|
||||
self:set_end_range(visual_range)
|
||||
|
||||
-- Ranged comments should always use the end of the range.
|
||||
-- Otherwise they will not highlight the full comment in Gitlab.
|
||||
self.location_data.old_line = self.location_data.line_range["end"].old_line
|
||||
self.location_data.new_line = self.location_data.line_range["end"].new_line
|
||||
end
|
||||
|
||||
-- Helper methods 🤝
|
||||
|
||||
-- Returns the matching line from the new SHA.
|
||||
-- For instance, line 12 in the new SHA may be scroll-linked
|
||||
-- to line 10 in the old SHA.
|
||||
---@param line number
|
||||
---@return number|nil
|
||||
function Location:get_line_number_from_new_sha(line)
|
||||
local reviewer = require("gitlab.reviewer")
|
||||
local is_current_sha_focused = reviewer.is_current_sha_focused()
|
||||
if is_current_sha_focused then
|
||||
return line
|
||||
end
|
||||
-- Otherwise we want to get the matching line in the opposite buffer
|
||||
return hunks.calculate_matching_line_new(self.base_sha, self.head_sha, self.reviewer_data.file_name, line)
|
||||
end
|
||||
|
||||
-- Returns the matching line from the old SHA.
|
||||
-- For instance, line 12 in the new SHA may be scroll-linked
|
||||
-- to line 10 in the old SHA.
|
||||
---@param line number
|
||||
---@return number|nil
|
||||
function Location:get_line_number_from_old_sha(line)
|
||||
local reviewer = require("gitlab.reviewer")
|
||||
local is_current_sha_focused = reviewer.is_current_sha_focused()
|
||||
if not is_current_sha_focused then
|
||||
return line
|
||||
end
|
||||
|
||||
-- Otherwise we want to get the matching line in the opposite buffer
|
||||
return hunks.calculate_matching_line_new(self.head_sha, self.base_sha, self.reviewer_data.file_name, line)
|
||||
end
|
||||
|
||||
-- Returns the current line number from whatever SHA (new or old)
|
||||
-- the reviewer is focused in.
|
||||
---@return number|nil
|
||||
function Location:get_current_line()
|
||||
local reviewer = require("gitlab.reviewer")
|
||||
local win_id = reviewer.is_current_sha_focused() and self.reviewer_data.new_sha_win_id
|
||||
or self.reviewer_data.old_sha_win_id
|
||||
if win_id == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local current_line = vim.api.nvim_win_get_cursor(win_id)[1]
|
||||
return current_line
|
||||
end
|
||||
|
||||
-- Given a new_line and old_line from the start of a ranged comment, returns the start
|
||||
-- range information for the Gitlab payload
|
||||
---@param visual_range LineRange
|
||||
---@return ReviewerLineInfo|nil
|
||||
function Location:set_start_range(visual_range)
|
||||
local current_file = require("gitlab.reviewer").get_current_file()
|
||||
if current_file == nil then
|
||||
u.notify("Error getting current file from Diffview", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local reviewer = require("gitlab.reviewer")
|
||||
local is_current_sha_focused = reviewer.is_current_sha_focused()
|
||||
local win_id = is_current_sha_focused and self.reviewer_data.new_sha_win_id or self.reviewer_data.old_sha_win_id
|
||||
if win_id == nil then
|
||||
u.notify("Error getting window number of SHA for start range", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local current_line = self:get_current_line()
|
||||
if current_line == nil then
|
||||
u.notify("Error getting current line for start range", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local new_line = self:get_line_number_from_new_sha(visual_range.start_line)
|
||||
local old_line = self:get_line_number_from_old_sha(visual_range.start_line)
|
||||
if
|
||||
(new_line == nil and self.reviewer_data.modification_type ~= "deleted")
|
||||
or (old_line == nil and self.reviewer_data.modification_type ~= "added")
|
||||
then
|
||||
u.notify("Error getting new or old line for start range", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local modification_type = hunks.get_modification_type(old_line, new_line, current_file, is_current_sha_focused)
|
||||
if modification_type == nil then
|
||||
u.notify("Error getting modification type for start of range", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
self.location_data.line_range.start = {
|
||||
new_line = modification_type ~= "deleted" and new_line or nil,
|
||||
old_line = modification_type ~= "added" and old_line or nil,
|
||||
type = modification_type == "added" and "new" or "old",
|
||||
}
|
||||
end
|
||||
|
||||
-- Given a modification type, a range, and the hunk data, returns the end range information
|
||||
-- for the Gitlab payload
|
||||
---@param visual_range LineRange
|
||||
function Location:set_end_range(visual_range)
|
||||
local current_file = require("gitlab.reviewer").get_current_file()
|
||||
if current_file == nil then
|
||||
u.notify("Error getting current file from Diffview", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local current_line = self:get_current_line()
|
||||
if current_line == nil then
|
||||
u.notify("Error getting current line for end range", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local new_line = self:get_line_number_from_new_sha(visual_range.end_line)
|
||||
local old_line = self:get_line_number_from_old_sha(visual_range.end_line)
|
||||
|
||||
if
|
||||
(new_line == nil and self.reviewer_data.modification_type ~= "deleted")
|
||||
or (old_line == nil and self.reviewer_data.modification_type ~= "added")
|
||||
then
|
||||
u.notify("Error getting new or old line for end range", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local reviewer = require("gitlab.reviewer")
|
||||
local is_current_sha_focused = reviewer.is_current_sha_focused()
|
||||
local modification_type = hunks.get_modification_type(old_line, new_line, current_file, is_current_sha_focused)
|
||||
if modification_type == nil then
|
||||
u.notify("Error getting modification type for end of range", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
self.location_data.line_range["end"] = {
|
||||
new_line = modification_type ~= "deleted" and new_line or nil,
|
||||
old_line = modification_type ~= "added" and old_line or nil,
|
||||
type = modification_type == "added" and "new" or "old",
|
||||
}
|
||||
end
|
||||
|
||||
return Location
|
||||
Reference in New Issue
Block a user