|
3 | 3 | --- to this module the data required to make the API calls |
4 | 4 | local Popup = require("nui.popup") |
5 | 5 | local Layout = require("nui.layout") |
6 | | -local diffview_lib = require("diffview.lib") |
7 | 6 | local state = require("gitlab.state") |
8 | 7 | local job = require("gitlab.job") |
9 | 8 | local u = require("gitlab.utils") |
@@ -47,6 +46,18 @@ local confirm_create_comment = function(text, visual_range, unlinked, discussion |
47 | 46 | return |
48 | 47 | end |
49 | 48 |
|
| 49 | + -- Creating a draft reply, in response to a discussion ID |
| 50 | + if discussion_id ~= nil and is_draft then |
| 51 | + local body = { comment = text, discussion_id = discussion_id } |
| 52 | + job.run_job("/mr/draft_notes/", "POST", body, function() |
| 53 | + u.notify("Draft reply created!", vim.log.levels.INFO) |
| 54 | + draft_notes.load_draft_notes(function() |
| 55 | + discussions.rebuild_view(unlinked) |
| 56 | + end) |
| 57 | + end) |
| 58 | + return |
| 59 | + end |
| 60 | + |
50 | 61 | -- Creating a note (unlinked comment) |
51 | 62 | if unlinked and discussion_id == nil then |
52 | 63 | local body = { comment = text } |
@@ -90,18 +101,6 @@ local confirm_create_comment = function(text, visual_range, unlinked, discussion |
90 | 101 | line_range = location_data.line_range, |
91 | 102 | } |
92 | 103 |
|
93 | | - -- Creating a draft reply, in response to a discussion ID |
94 | | - if discussion_id ~= nil and is_draft then |
95 | | - local body = { comment = text, discussion_id = discussion_id, position = position_data } |
96 | | - job.run_job("/mr/draft_notes/", "POST", body, function() |
97 | | - u.notify("Draft reply created!", vim.log.levels.INFO) |
98 | | - draft_notes.load_draft_notes(function() |
99 | | - discussions.rebuild_view(unlinked) |
100 | | - end) |
101 | | - end) |
102 | | - return |
103 | | - end |
104 | | - |
105 | 104 | -- Creating a new comment (linked to specific changes) |
106 | 105 | local body = u.merge({ type = "text", comment = text }, position_data) |
107 | 106 | local endpoint = is_draft and "/mr/draft_notes/" or "/mr/comment" |
|
158 | 157 | ---multi-line comment. It also sets up the basic keybindings for switching between |
159 | 158 | ---window panes, and for the non-primary sections. |
160 | 159 | ---@param opts LayoutOpts |
161 | | ----@return NuiLayout|nil |
| 160 | +---@return NuiLayout |
162 | 161 | M.create_comment_layout = function(opts) |
163 | | - if opts.unlinked ~= true and opts.discussion_id == nil then |
164 | | - -- Check that diffview is initialized |
165 | | - if reviewer.tabnr == nil then |
166 | | - u.notify("Reviewer must be initialized first", vim.log.levels.ERROR) |
167 | | - return |
168 | | - end |
169 | | - |
170 | | - -- Check that Diffview is the current view |
171 | | - local view = diffview_lib.get_current_view() |
172 | | - if view == nil and not opts.reply then |
173 | | - u.notify("Comments should be left in the reviewer pane", vim.log.levels.ERROR) |
174 | | - return |
175 | | - end |
176 | | - |
177 | | - -- Check that we are in the diffview tab |
178 | | - local tabnr = vim.api.nvim_get_current_tabpage() |
179 | | - if tabnr ~= reviewer.tabnr then |
180 | | - u.notify("Line location can only be determined within reviewer window", vim.log.levels.ERROR) |
181 | | - return |
182 | | - end |
183 | | - |
184 | | - -- Check that the file has not been renamed |
185 | | - if reviewer.is_file_renamed() and not reviewer.does_file_have_changes() then |
186 | | - u.notify("Commenting on (unchanged) renamed or moved files is not supported", vim.log.levels.WARN) |
187 | | - return |
188 | | - end |
189 | | - |
190 | | - -- Check that we are hovering over the code |
191 | | - local filetype = vim.bo[0].filetype |
192 | | - if not opts.reply and (filetype == "DiffviewFiles" or filetype == "gitlab") then |
193 | | - u.notify( |
194 | | - "Comments can only be left on the code. To leave unlinked comments, use gitlab.create_note() instead", |
195 | | - vim.log.levels.ERROR |
196 | | - ) |
197 | | - return |
198 | | - end |
199 | | - end |
200 | | - |
201 | 162 | local popup_settings = state.settings.popup |
202 | 163 | local title |
203 | 164 | local user_settings |
@@ -262,53 +223,31 @@ end |
262 | 223 | --- This function will open a comment popup in order to create a comment on the changed/updated |
263 | 224 | --- line in the current MR |
264 | 225 | M.create_comment = function() |
265 | | - local has_clean_tree, err = git.has_clean_tree() |
266 | | - if err ~= nil then |
267 | | - return |
268 | | - end |
269 | | - |
270 | | - local is_modified = vim.bo[0].modified |
271 | | - if state.settings.reviewer_settings.diffview.imply_local and (is_modified or not has_clean_tree) then |
272 | | - u.notify( |
273 | | - "Cannot leave comments on changed files. \n Please stash all local changes or push them to the feature branch.", |
274 | | - vim.log.levels.WARN |
275 | | - ) |
276 | | - return |
277 | | - end |
278 | | - |
279 | | - if not M.sha_exists() then |
| 226 | + if not M.can_create_comment(false) then |
280 | 227 | return |
281 | 228 | end |
282 | 229 |
|
283 | 230 | local layout = M.create_comment_layout({ ranged = false, unlinked = false }) |
284 | | - if layout ~= nil then |
285 | | - layout:mount() |
286 | | - end |
| 231 | + layout:mount() |
287 | 232 | end |
288 | 233 |
|
289 | 234 | --- This function will open a multi-line comment popup in order to create a multi-line comment |
290 | 235 | --- on the changed/updated line in the current MR |
291 | 236 | M.create_multiline_comment = function() |
292 | | - if not u.check_visual_mode() then |
293 | | - return |
294 | | - end |
295 | | - if not M.sha_exists() then |
| 237 | + if not M.can_create_comment(true) then |
| 238 | + u.press_escape() |
296 | 239 | return |
297 | 240 | end |
298 | 241 |
|
299 | 242 | local layout = M.create_comment_layout({ ranged = true, unlinked = false }) |
300 | | - if layout ~= nil then |
301 | | - layout:mount() |
302 | | - end |
| 243 | + layout:mount() |
303 | 244 | end |
304 | 245 |
|
305 | 246 | --- This function will open a a popup to create a "note" (e.g. unlinked comment) |
306 | 247 | --- on the changed/updated line in the current MR |
307 | 248 | M.create_note = function() |
308 | 249 | local layout = M.create_comment_layout({ ranged = false, unlinked = true }) |
309 | | - if layout ~= nil then |
310 | | - layout:mount() |
311 | | - end |
| 250 | + layout:mount() |
312 | 251 | end |
313 | 252 |
|
314 | 253 | ---Given the current visually selected area of text, builds text to fill in the |
@@ -353,28 +292,85 @@ end |
353 | 292 | --- on the changed/updated line in the current MR |
354 | 293 | --- See: https://docs.gitlab.com/ee/user/project/merge_requests/reviews/suggestions.html |
355 | 294 | M.create_comment_suggestion = function() |
356 | | - if not u.check_visual_mode() then |
357 | | - return |
358 | | - end |
359 | | - if not M.sha_exists() then |
| 295 | + if not M.can_create_comment(true) then |
| 296 | + u.press_escape() |
360 | 297 | return |
361 | 298 | end |
362 | 299 |
|
363 | 300 | local suggestion_lines, range_length = build_suggestion() |
364 | 301 |
|
365 | 302 | local layout = M.create_comment_layout({ ranged = range_length > 0, unlinked = false }) |
366 | | - if layout ~= nil then |
367 | | - layout:mount() |
368 | | - else |
369 | | - return -- Failure in creating the comment layout |
370 | | - end |
| 303 | + layout:mount() |
| 304 | + |
371 | 305 | vim.schedule(function() |
372 | 306 | if suggestion_lines then |
373 | 307 | vim.api.nvim_buf_set_lines(M.comment_popup.bufnr, 0, -1, false, suggestion_lines) |
374 | 308 | end |
375 | 309 | end) |
376 | 310 | end |
377 | 311 |
|
| 312 | +---Returns true if it's possible to create an Inline Comment |
| 313 | +---@param must_be_visual boolean True if current mode must be visual |
| 314 | +---@return boolean |
| 315 | +M.can_create_comment = function(must_be_visual) |
| 316 | + -- Check that diffview is initialized |
| 317 | + if reviewer.tabnr == nil then |
| 318 | + u.notify("Reviewer must be initialized first", vim.log.levels.ERROR) |
| 319 | + return false |
| 320 | + end |
| 321 | + |
| 322 | + -- Check that we are in the Diffview tab |
| 323 | + local tabnr = vim.api.nvim_get_current_tabpage() |
| 324 | + if tabnr ~= reviewer.tabnr then |
| 325 | + u.notify("Comments can only be left in the reviewer pane", vim.log.levels.ERROR) |
| 326 | + return false |
| 327 | + end |
| 328 | + |
| 329 | + -- Check that we are hovering over the code |
| 330 | + local filetype = vim.bo[0].filetype |
| 331 | + if filetype == "DiffviewFiles" or filetype == "gitlab" then |
| 332 | + u.notify( |
| 333 | + "Comments can only be left on the code. To leave unlinked comments, use gitlab.create_note() instead", |
| 334 | + vim.log.levels.ERROR |
| 335 | + ) |
| 336 | + return false |
| 337 | + end |
| 338 | + |
| 339 | + -- Check that the file has not been renamed |
| 340 | + if reviewer.is_file_renamed() and not reviewer.does_file_have_changes() then |
| 341 | + u.notify("Commenting on (unchanged) renamed or moved files is not supported", vim.log.levels.ERROR) |
| 342 | + return false |
| 343 | + end |
| 344 | + |
| 345 | + -- Check that we are in a valid buffer |
| 346 | + if not M.sha_exists() then |
| 347 | + return false |
| 348 | + end |
| 349 | + |
| 350 | + -- Check that there aren't saved modifications |
| 351 | + local file = reviewer.get_current_file_path() |
| 352 | + if file == nil then |
| 353 | + return false |
| 354 | + end |
| 355 | + local has_changes, err = git.has_changes(file) |
| 356 | + if err ~= nil then |
| 357 | + return false |
| 358 | + end |
| 359 | + -- Check that there aren't unsaved modifications |
| 360 | + local is_modified = vim.bo[0].modified |
| 361 | + if state.settings.reviewer_settings.diffview.imply_local and (is_modified or has_changes) then |
| 362 | + u.notify("Cannot leave comments on changed files, please stash or commit and push", vim.log.levels.ERROR) |
| 363 | + return false |
| 364 | + end |
| 365 | + |
| 366 | + -- Check we're in visual mode for code suggestions and multiline comments |
| 367 | + if must_be_visual and not u.check_visual_mode() then |
| 368 | + return false |
| 369 | + end |
| 370 | + |
| 371 | + return true |
| 372 | +end |
| 373 | + |
378 | 374 | ---Checks to see whether you are commenting on a valid buffer. The Diffview plugin names non-existent |
379 | 375 | ---buffers as 'null' |
380 | 376 | ---@return boolean |
|
0 commit comments