-
Notifications
You must be signed in to change notification settings - Fork 48
Draft: Feat: Add suggestions functionality #504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
9c2265f
a2b7651
09314cf
214068a
17a69d7
6049705
3cbdf51
282899f
9547446
5b11f20
6d9f83a
394d5f7
f056e0c
bc3ee7f
b586f1b
478baa4
844fffa
01dcfc0
9e1bdf5
69b884a
c14ea7e
3d41624
f02c608
02e3522
078236f
db0ef39
5734b10
926ae2e
10e1467
833c741
33e0b02
a661059
5b38506
2475ce3
3c48880
3992cef
5d8f792
6fccdbf
17cc275
fba0395
98f692f
21bde2d
7bb39ac
0add185
63306b5
79c8caf
3795201
983eb59
3f778f0
6ed9e3f
9dbc478
13a9fd2
1ad7e7d
3813732
8264286
821791f
8e487a8
6a68922
675bc54
97be236
9f67c58
b753bb1
8120680
2964a00
01d1e23
0b1c55b
2b27933
53c3bb3
e9cbed1
2136a0e
e2872e4
cceebc8
ef7da2e
3dec6ee
e6931e0
efdf5b7
7f4f61f
8ac996e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,6 @@ local popup = require("gitlab.popup") | |
local state = require("gitlab.state") | ||
local reviewer = require("gitlab.reviewer") | ||
local common = require("gitlab.actions.common") | ||
local List = require("gitlab.utils.list") | ||
local tree_utils = require("gitlab.actions.discussions.tree") | ||
local discussions_tree = require("gitlab.actions.discussions.tree") | ||
local draft_notes = require("gitlab.actions.draft_notes") | ||
|
@@ -240,12 +239,85 @@ M.reply = function(tree) | |
discussion_id = discussion_id, | ||
unlinked = unlinked, | ||
reply = true, | ||
-- TODO: use discussion_node.old_file_name for comments on unchanged lines in renamed files | ||
file_name = discussion_node.file_name, | ||
}) | ||
|
||
layout:mount() | ||
end | ||
|
||
---Open a new tab with a suggestion preview. | ||
---@param tree NuiTree The current discussion tree instance. | ||
---@param action "reply"|"edit"|"apply" Reply to the current thread, edit the current comment or apply the suggestion to local file. | ||
M.suggestion_preview = function(tree, action) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't working for me, the suggestion is hidden, and slowly expands each time I press a character funky-scroll.behavior.movThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember that I had the behaviour you describe before but then I added a fix for that, so maybe you need to pull the latest I'm still getting a similar behaviour when I leave the suggestion intact and only modify the comment above the" ```suggestion:-0+0" line. But as soon as I make a modification in the suggestion body itself, the diff is shown correctly. It would be best to fix this as well, I've experimented with different folding normal mode commands instead of zX, but haven't found a solution yet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've just pushed a fix that gets rid of the behaviour completely. |
||
local is_draft = M.is_draft_note(tree) | ||
if action == "reply" and is_draft then | ||
u.notify("Gitlab does not support replying to draft notes", vim.log.levels.WARN) | ||
return | ||
end | ||
|
||
local current_node = tree:get_node() | ||
local root_node = common.get_root_node(tree, current_node) | ||
local note_node = common.get_note_node(tree, current_node) | ||
|
||
-- Return early if note info is missing | ||
if root_node == nil or note_node == nil then | ||
u.notify("Couldn't get root node or note node", vim.log.levels.ERROR) | ||
return | ||
end | ||
local note_node_id = tonumber(note_node.is_root and note_node.root_note_id or note_node.id) | ||
if note_node_id == nil then | ||
u.notify("Couldn't get comment id", vim.log.levels.ERROR) | ||
return | ||
end | ||
|
||
-- Return early if comment position is missing | ||
local start_line, is_new_sha, end_line = common.get_line_number_from_node(root_node) | ||
if start_line == nil or end_line == nil then | ||
u.notify("Couldn't get comment range. Can't create suggestion preview", vim.log.levels.ERROR) | ||
return | ||
end | ||
|
||
-- Override reviewer values when local-applying a suggestion that was made on the OLD version | ||
if action == "apply" and not is_new_sha then | ||
local range = end_line - start_line | ||
start_line = common.get_new_line(root_node) | ||
|
||
if start_line == nil then | ||
u.notify("Couldn't get position in new version. Can't create suggestion preview", vim.log.levels.ERROR) | ||
return | ||
end | ||
|
||
end_line = start_line + range | ||
is_new_sha = true | ||
end | ||
|
||
-- Get values for preview depending on whether comment is on OLD or NEW version | ||
local revision | ||
if is_new_sha then | ||
revision = common.commented_line_has_changed(tree, root_node) and root_node.head_sha or "HEAD" | ||
else | ||
revision = root_node.base_sha | ||
end | ||
Comment on lines
+297
to
+301
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the comment is on the "NEW SHA", we can use HEAD as the original text of the suggestion and show it on the local file. Othewise we use the For this reason, I'd like to reverse the logic of showing comments on unmodified lines in the old file and show them in the new file whenever possible. What do you think? |
||
|
||
---@type ShowPreviewOpts | ||
local opts = { | ||
old_file_name = root_node.old_file_name, | ||
new_file_name = root_node.file_name, | ||
start_line = start_line, | ||
end_line = end_line, | ||
is_new_sha = is_new_sha, | ||
revision = revision, | ||
note_header = note_node.text, | ||
comment_type = is_draft and "draft" or action, | ||
note_lines = action ~= "reply" and common.get_note_lines(tree) or nil, | ||
root_node_id = root_node.id, | ||
note_node_id = note_node_id, | ||
tree = tree, | ||
} | ||
require("gitlab.actions.suggestions").show_preview(opts) | ||
end | ||
|
||
-- This function (settings.keymaps.discussion_tree.delete_comment) will trigger a popup prompting you to delete the current comment | ||
M.delete_comment = function(tree, unlinked) | ||
vim.ui.select({ "Confirm", "Cancel" }, { | ||
|
@@ -289,15 +361,7 @@ M.edit_comment = function(tree, unlinked) | |
|
||
edit_popup:mount() | ||
|
||
-- Gather all lines from immediate children that aren't note nodes | ||
local lines = List.new(note_node:get_child_ids()):reduce(function(agg, child_id) | ||
local child_node = tree:get_node(child_id) | ||
if not child_node:has_children() then | ||
local line = tree:get_node(child_id).text | ||
table.insert(agg, line) | ||
end | ||
return agg | ||
end, {}) | ||
local lines = common.get_note_lines(tree) | ||
|
||
local currentBuffer = vim.api.nvim_get_current_buf() | ||
vim.api.nvim_buf_set_lines(currentBuffer, 0, -1, false, lines) | ||
|
@@ -322,7 +386,9 @@ M.edit_comment = function(tree, unlinked) | |
end | ||
|
||
-- This function (settings.keymaps.discussion_tree.toggle_discussion_resolved) will toggle the resolved status of the current discussion and send the change to the Go server | ||
M.toggle_discussion_resolved = function(tree) | ||
---@param tree NuiTree | ||
---@param override boolean|nil If not nil, set resolved to `override` value instead of toggling. | ||
M.toggle_discussion_resolved = function(tree, override) | ||
local note = tree:get_node() | ||
if note == nil then | ||
return | ||
|
@@ -336,9 +402,16 @@ M.toggle_discussion_resolved = function(tree) | |
return | ||
end | ||
|
||
local resolved | ||
if override ~= nil then | ||
resolved = override | ||
else | ||
resolved = not note.resolved | ||
end | ||
|
||
local body = { | ||
discussion_id = note.id, | ||
resolved = not note.resolved, | ||
resolved = resolved, | ||
} | ||
|
||
job.run_job("/mr/discussions/resolve", "PUT", body, function(data) | ||
|
@@ -593,6 +666,34 @@ M.set_tree_keymaps = function(tree, bufnr, unlinked) | |
nowait = keymaps.discussion_tree.toggle_tree_type_nowait, | ||
}) | ||
end | ||
|
||
if keymaps.discussion_tree.edit_suggestion then | ||
vim.keymap.set("n", keymaps.discussion_tree.edit_suggestion, function() | ||
if M.is_current_node_note(tree) then | ||
M.suggestion_preview(tree, "edit") | ||
end | ||
end, { buffer = bufnr, desc = "Edit suggestion", nowait = keymaps.discussion_tree.edit_suggestion_nowait }) | ||
end | ||
|
||
if keymaps.discussion_tree.apply_suggestion then | ||
vim.keymap.set("n", keymaps.discussion_tree.apply_suggestion, function() | ||
if M.is_current_node_note(tree) then | ||
M.suggestion_preview(tree, "apply") | ||
end | ||
end, { buffer = bufnr, desc = "Apply suggestion", nowait = keymaps.discussion_tree.apply_suggestion_nowait }) | ||
end | ||
|
||
if keymaps.discussion_tree.reply_with_suggestion then | ||
vim.keymap.set("n", keymaps.discussion_tree.reply_with_suggestion, function() | ||
if M.is_current_node_note(tree) then | ||
M.suggestion_preview(tree, "reply") | ||
end | ||
end, { | ||
buffer = bufnr, | ||
desc = "Reply with suggestion", | ||
nowait = keymaps.discussion_tree.reply_with_suggestion_nowait, | ||
}) | ||
end | ||
end | ||
|
||
if keymaps.discussion_tree.refresh_data then | ||
|
@@ -805,6 +906,10 @@ end | |
---Toggle between draft mode (comments posted as drafts) and live mode (comments are posted immediately) | ||
M.toggle_draft_mode = function() | ||
state.settings.discussion_tree.draft_mode = not state.settings.discussion_tree.draft_mode | ||
vim.api.nvim_exec_autocmds("User", { | ||
pattern = "GitlabDraftModeToggled", | ||
data = { draft_mode = state.settings.discussion_tree.draft_mode }, | ||
}) | ||
end | ||
|
||
---Toggle between sorting by "original comment" (oldest at the top) or "latest reply" (newest at the | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be just "S" since that's a native Vim binding and won't trigger right away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Harrison, thanks for looking at this! I'm using exactly this mapping without a problem. The builtin "S" is remapped the same was as "s" for "create_suggestion". The builtin behaviour is "delete lines", so it does trigger right away, what may be happening is that this mapping conflicts with another plugin (Folke's Flash suggests to remap "S", so maybe that). This can be fixed with the
create_suggestion_with_preview_nowait = true,
setting in gitlab.nvim config.But of course I can choose a different default and remap it in my personal config if you prefer that.