diff --git a/doc/gitlab.nvim.txt b/doc/gitlab.nvim.txt index 4c8dc128..d43afa2c 100644 --- a/doc/gitlab.nvim.txt +++ b/doc/gitlab.nvim.txt @@ -155,6 +155,7 @@ you call this function with no values the defaults will be used: debug = { go_request = false, go_response = false }, -- Which values to log attachment_dir = nil, -- The local directory for files (see the "summary" section) reviewer_settings = { + jump_with_no_diagnostics = false, -- Jump to last position in discussion tree if true, otherwise stay in reviewer and show warning. diffview = { imply_local = false, -- If true, will attempt to use --imply_local option when calling |:DiffviewOpen| }, @@ -651,22 +652,31 @@ Reviewer keybindings ~ Most of the keybindings `gitlab.nvim` sets are normal mode mappings, with the exception of `keymaps.reviewer.create_comment` and `keymaps.reviewer.create_suggestion` which work in both normal and visual -mode. In normal mode, these keybindings are |operator|s that accept a |motion| -(with an optional |count|). E.g., `c2j` will create a comment for the current -and the next 2 lines. Similarly, `sip` will create a suggestion for the "inner -paragraph". The operator forces |linewise| visual selection, so it works -correctly even if the motion itself works |characterwise| (e.g., |i(| for -selecting the inner parentheses block). +mode. In normal mode, these keybindings are |operator|s that must be followed +by a |motion|. + +Either the operator or the motion can be preceded by a count, so that `3sj` is +equivalent to `s3j`, and they both create a comment for the current line and +three more lines downwards. Similarly, both `2s`|ap| and `s2`|ap| create a suggestion +for two "outer" paragraphs. + +The operators force |linewise| visual selection, so they work correctly even +if the motion itself works |characterwise| (e.g., |i(| for selecting the inner +parentheses block). + +To create a comment or suggestion for the current line, just duplicate the +keybinding: `cc` and `ss`. This also accepts a count, so you can use `2cc` or +`c2c` to create a comment on two lines. The same logic applies also when you +change these keybindings, e.g., to something like `c`. The keybindings also work in visual mode, e.g., if you first want to make sure you are commenting on the right text segment/object, you can do `v4j` to visually select the current and the next 4 lines, followed by either `c` for a normal comment or `s` for a suggestion. -To create a comment or suggestion for the current line, just duplicate the -keybinding: `cc` and `ss`. Alternatively, you can use any motion that moves on -that line only, e.g., `c$`. The same logic applies also when you change these -keybindings, e.g., to something like `c`. +NOTE: Due to limitations of the Nvim API, unlike with builtin operators `d`, `c`, +etc., the operator count and motion count are NOT |multiplied|, so that the key +presses `3s2s` are not equivalent to `6ss`, but result in `s32s`. Delay in keybindings ~ diff --git a/lua/gitlab/actions/discussions/init.lua b/lua/gitlab/actions/discussions/init.lua index cc5421b6..5e7cfdda 100644 --- a/lua/gitlab/actions/discussions/init.lua +++ b/lua/gitlab/actions/discussions/init.lua @@ -202,7 +202,12 @@ M.move_to_discussion_tree = function() end if #d == 0 then - u.notify("No diagnostics for this line", vim.log.levels.WARN) + if state.settings.reviewer_settings.jump_with_no_diagnostics then + vim.api.nvim_win_set_cursor(M.split.winid, { M.last_row, M.last_column }) + vim.api.nvim_set_current_win(M.split.winid) + else + u.notify("No diagnostics for this line.", vim.log.levels.WARN) + end return elseif #d > 1 then vim.ui.select(d, { @@ -518,6 +523,13 @@ M.create_split_and_bufs = function() local linked_bufnr = vim.api.nvim_create_buf(true, false) local unlinked_bufnr = vim.api.nvim_create_buf(true, false) + vim.api.nvim_create_autocmd("WinLeave", { + buffer = linked_bufnr, + callback = function() + M.last_row, M.last_column = unpack(vim.api.nvim_win_get_cursor(0)) + end, + }) + return split, linked_bufnr, unlinked_bufnr end diff --git a/lua/gitlab/actions/help.lua b/lua/gitlab/actions/help.lua index 1db04489..d76c7b5e 100644 --- a/lua/gitlab/actions/help.lua +++ b/lua/gitlab/actions/help.lua @@ -1,6 +1,7 @@ local M = {} local u = require("gitlab.utils") +local event = require("nui.utils.autocmd").event local state = require("gitlab.state") local List = require("gitlab.utils.list") local Popup = require("nui.popup") @@ -18,11 +19,15 @@ M.open = function() local longest_line = u.get_longest_string(help_content_lines) local help_popup = Popup(u.create_popup_state("Help", state.settings.popup.help, longest_line + 3, #help_content_lines + 3, 60)) + help_popup:on(event.BufLeave, function() + help_popup:unmount() + end) help_popup:mount() state.set_popup_keymaps(help_popup, "Help", nil) local currentBuffer = vim.api.nvim_get_current_buf() vim.api.nvim_buf_set_lines(currentBuffer, 0, #help_content_lines, false, help_content_lines) + u.switch_can_edit_buf(currentBuffer, false) end return M diff --git a/lua/gitlab/reviewer/init.lua b/lua/gitlab/reviewer/init.lua index 1b32e9a0..ed0cce95 100644 --- a/lua/gitlab/reviewer/init.lua +++ b/lua/gitlab/reviewer/init.lua @@ -276,8 +276,9 @@ M.set_callback_for_reviewer_enter = function(callback) }) end ----Create the line-wise visual selection in the range of the motion and execute the gitlab.nvim API ----function. After that, restore the cursor position and the original operatorfunc. +---Create the line-wise visual selection in the range of the motion (or on the [count] number of +---lines) and execute the gitlab.nvim API function. After that, restore the cursor position and the +---original operatorfunc. ---@param callback string Name of the gitlab.nvim API function to call M.execute_callback = function(callback) return function() @@ -299,7 +300,9 @@ local function execute_operatorfunc(cb) M.old_winnr = vim.api.nvim_get_current_win() M.old_cursor_position = vim.api.nvim_win_get_cursor(M.old_winnr) vim.opt.operatorfunc = ("v:lua.require'gitlab.reviewer'.execute_callback'%s'"):format(cb) - vim.api.nvim_feedkeys("g@", "n", false) + -- Use the operator count before motion to allow, e.g., 2cc == c2c + local count = M.operator_count > 0 and tostring(M.operator_count) or "" + vim.api.nvim_feedkeys("g@" .. count, "n", false) end ---Set keymaps for creating comments, suggestions and for jumping to discussion tree. @@ -308,16 +311,21 @@ end local set_keymaps = function(bufnr, keymaps) -- Set mappings for creating comments if keymaps.reviewer.create_comment ~= false then - vim.keymap.set( - "o", - keymaps.reviewer.create_comment, - "$", - { buffer = bufnr, desc = "Create comment for current line", nowait = keymaps.reviewer.create_comment_nowait } - ) + -- Set keymap for repeated operator keybinding + vim.keymap.set("o", keymaps.reviewer.create_comment, function() + vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { tostring(vim.v.count1) .. "j" } }, {}) + end, { + buffer = bufnr, + desc = "Create comment for [count] lines", + nowait = keymaps.reviewer.create_comment_nowait, + }) + + -- Set operator keybinding vim.keymap.set( "n", keymaps.reviewer.create_comment, function() + M.operator_count = vim.v.count execute_operatorfunc("create_multiline_comment") end, { buffer = bufnr, desc = "Create comment for range of motion", nowait = keymaps.reviewer.create_comment_nowait } @@ -333,18 +341,27 @@ local set_keymaps = function(bufnr, keymaps) -- Set mappings for creating suggestions if keymaps.reviewer.create_suggestion ~= false then - vim.keymap.set("o", keymaps.reviewer.create_suggestion, "$", { + -- Set keymap for repeated operator keybinding + vim.keymap.set("o", keymaps.reviewer.create_suggestion, function() + vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { tostring(vim.v.count1) .. "j" } }, {}) + end, { buffer = bufnr, - desc = "Create suggestion for current line", + desc = "Create suggestion for [count] lines", nowait = keymaps.reviewer.create_suggestion_nowait, }) + + -- Set operator keybinding vim.keymap.set("n", keymaps.reviewer.create_suggestion, function() + M.operator_count = vim.v.count + M.operator = keymaps.reviewer.create_suggestion execute_operatorfunc("create_comment_suggestion") end, { buffer = bufnr, desc = "Create suggestion for range of motion", nowait = keymaps.reviewer.create_suggestion_nowait, }) + + -- Set visual mode keybinding vim.keymap.set("v", keymaps.reviewer.create_suggestion, function() require("gitlab").create_comment_suggestion() end, { diff --git a/lua/gitlab/state.lua b/lua/gitlab/state.lua index a359d7f8..a5b8f583 100644 --- a/lua/gitlab/state.lua +++ b/lua/gitlab/state.lua @@ -52,6 +52,7 @@ M.settings = { config_path = nil, reviewer = "diffview", reviewer_settings = { + jump_with_no_diagnostics = false, diffview = { imply_local = false, },