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.
164 lines
5.7 KiB
Lua
164 lines
5.7 KiB
Lua
-- This module is responsible for creating new comments
|
|
-- in the reviewer's buffer. The reviewer will pass back
|
|
-- to this module the data required to make the API calls
|
|
local Popup = require("nui.popup")
|
|
local state = require("gitlab.state")
|
|
local job = require("gitlab.job")
|
|
local u = require("gitlab.utils")
|
|
local git = require("gitlab.git")
|
|
local discussions = require("gitlab.actions.discussions")
|
|
local miscellaneous = require("gitlab.actions.miscellaneous")
|
|
local reviewer = require("gitlab.reviewer")
|
|
local Location = require("gitlab.reviewer.location")
|
|
local M = {}
|
|
|
|
-- Popup creation is wrapped in a function so that it is performed *after* user
|
|
-- configuration has been merged with default configuration, not when this file is being
|
|
-- required.
|
|
local function create_comment_popup()
|
|
return Popup(u.create_popup_state("Comment", state.settings.popup.comment))
|
|
end
|
|
|
|
-- This function will open a comment popup in order to create a comment on the changed/updated
|
|
-- line in the current MR
|
|
M.create_comment = function()
|
|
local has_clean_tree = git.has_clean_tree()
|
|
local is_modified = vim.api.nvim_buf_get_option(0, "modified")
|
|
if state.settings.reviewer_settings.diffview.imply_local and (is_modified or not has_clean_tree) then
|
|
u.notify(
|
|
"Cannot leave comments on changed files. \n Please stash all local changes or push them to the feature branch.",
|
|
vim.log.levels.WARN
|
|
)
|
|
return
|
|
end
|
|
local comment_popup = create_comment_popup()
|
|
comment_popup:mount()
|
|
state.set_popup_keymaps(comment_popup, function(text)
|
|
M.confirm_create_comment(text)
|
|
end, miscellaneous.attach_file)
|
|
end
|
|
|
|
---Create multiline comment for the last selection.
|
|
M.create_multiline_comment = function()
|
|
if not u.check_visual_mode() then
|
|
return
|
|
end
|
|
local comment_popup = create_comment_popup()
|
|
local start_line, end_line = u.get_visual_selection_boundaries()
|
|
comment_popup:mount()
|
|
state.set_popup_keymaps(comment_popup, function(text)
|
|
M.confirm_create_comment(text, { start_line = start_line, end_line = end_line })
|
|
end, miscellaneous.attach_file)
|
|
end
|
|
|
|
---Create comment prepopulated with gitlab suggestion
|
|
---https://docs.gitlab.com/ee/user/project/merge_requests/reviews/suggestions.html
|
|
M.create_comment_suggestion = function()
|
|
if not u.check_visual_mode() then
|
|
return
|
|
end
|
|
local comment_popup = create_comment_popup()
|
|
local start_line, end_line = u.get_visual_selection_boundaries()
|
|
local current_line = vim.api.nvim_win_get_cursor(0)[1]
|
|
local range = end_line - start_line
|
|
local backticks = "```"
|
|
local selected_lines = reviewer.get_lines(start_line, end_line)
|
|
|
|
for line in ipairs(selected_lines) do
|
|
if string.match(line, "^```$") then
|
|
backticks = "````"
|
|
break
|
|
end
|
|
end
|
|
|
|
local suggestion_start
|
|
if start_line == current_line then
|
|
suggestion_start = backticks .. "suggestion:-0+" .. range
|
|
elseif end_line == current_line then
|
|
suggestion_start = backticks .. "suggestion:-" .. range .. "+0"
|
|
else
|
|
-- This should never happen afaik
|
|
u.notify("Unexpected suggestion position", vim.log.levels.ERROR)
|
|
return
|
|
end
|
|
suggestion_start = suggestion_start
|
|
local suggestion_lines = {}
|
|
table.insert(suggestion_lines, suggestion_start)
|
|
vim.list_extend(suggestion_lines, selected_lines)
|
|
table.insert(suggestion_lines, backticks)
|
|
|
|
comment_popup:mount()
|
|
vim.api.nvim_buf_set_lines(comment_popup.bufnr, 0, -1, false, suggestion_lines)
|
|
state.set_popup_keymaps(comment_popup, function(text)
|
|
if range > 0 then
|
|
M.confirm_create_comment(text, { start_line = start_line, end_line = end_line })
|
|
else
|
|
M.confirm_create_comment(text, nil)
|
|
end
|
|
end, miscellaneous.attach_file)
|
|
end
|
|
|
|
M.create_note = function()
|
|
local note_popup = Popup(u.create_popup_state("Note", state.settings.popup.note))
|
|
note_popup:mount()
|
|
state.set_popup_keymaps(note_popup, function(text)
|
|
M.confirm_create_comment(text, nil, true)
|
|
end, miscellaneous.attach_file)
|
|
end
|
|
|
|
---This function (settings.popup.perform_action) will send the comment to the Go server
|
|
---@param text string comment text
|
|
---@param visual_range LineRange | nil range of visual selection or nil
|
|
---@param unlinked boolean | nil if true, the comment is not linked to a line
|
|
M.confirm_create_comment = function(text, visual_range, unlinked)
|
|
if text == nil then
|
|
u.notify("Reviewer did not provide text of change", vim.log.levels.ERROR)
|
|
return
|
|
end
|
|
|
|
if unlinked then
|
|
local body = { comment = text }
|
|
job.run_job("/mr/comment", "POST", body, function(data)
|
|
u.notify("Note created!", vim.log.levels.INFO)
|
|
discussions.add_discussion({ data = data, unlinked = true })
|
|
discussions.refresh()
|
|
end)
|
|
return
|
|
end
|
|
|
|
local reviewer_data = reviewer.get_reviewer_data()
|
|
if reviewer_data == nil then
|
|
u.notify("Error getting reviewer data", vim.log.levels.ERROR)
|
|
return
|
|
end
|
|
|
|
local location = Location.new(reviewer_data, visual_range)
|
|
location:build_location_data()
|
|
local location_data = location.location_data
|
|
if location_data == nil then
|
|
u.notify("Error getting location information", vim.log.levels.ERROR)
|
|
return
|
|
end
|
|
|
|
local revision = state.MR_REVISIONS[1]
|
|
local body = {
|
|
type = "text",
|
|
comment = text,
|
|
file_name = reviewer_data.file_name,
|
|
base_commit_sha = revision.base_commit_sha,
|
|
start_commit_sha = revision.start_commit_sha,
|
|
head_commit_sha = revision.head_commit_sha,
|
|
old_line = location_data.old_line,
|
|
new_line = location_data.new_line,
|
|
line_range = location_data.line_range,
|
|
}
|
|
|
|
job.run_job("/mr/comment", "POST", body, function(data)
|
|
u.notify("Comment created!", vim.log.levels.INFO)
|
|
discussions.add_discussion({ data = data, unlinked = false })
|
|
discussions.refresh()
|
|
end)
|
|
end
|
|
|
|
return M
|