- allows SSH Gitlab connection to have custom port - introduces temporary registers - fixes issue w/ quitting the popup on MR creation This is a #MINOR release
164 lines
5.8 KiB
Lua
164 lines
5.8 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, miscellaneous.editable_popup_opts)
|
|
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, miscellaneous.editable_popup_opts)
|
|
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 = u.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, miscellaneous.editable_popup_opts)
|
|
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, miscellaneous.editable_popup_opts)
|
|
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
|