From ad33db5d4970daf6944813f61ca67dea81984586 Mon Sep 17 00:00:00 2001 From: ldelossa Date: Mon, 27 Jan 2025 18:00:56 -0500 Subject: [PATCH] fix: use user command lines ranges This is a follow to making line selections work via the command line. The crux of the confusion with this is that entering the command line from any other mode then normal, exits that mode, and enters normal mode. Octo was trying to determine a selected line range, retroactively, when adding review comments. However, this doesn't really work since if you highlight a line, then want to run the comment add command, you exit visual mode. All 'state' related to visual mode and visual line rages are greedy and never 'reset' to 0 when visual mode is exited. The "right" way that Vim intends you to figure out if a user command is being ran with a visual selection is by using the options dictionary provided to the command. Octo has a object/action lookup mechanism which hides this user command options dictionary from the handlers. This commit tries to fix the above issue without change how every single object/action is called by creating a global variable `OctoLastCmdOpts` which caches the last command's options. This can be used to gather the line range in which teh command was called. Ideally, the object/action function dispatch function is updated to pass the user-command dictionary to all command handlers, but this is a larger change. Signed-off-by: ldelossa --- lua/octo/commands.lua | 12 ++++++++++++ lua/octo/reviews/init.lua | 9 ++++++++- lua/octo/utils.lua | 4 ++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lua/octo/commands.lua b/lua/octo/commands.lua index 6fa92808..8cdd7aad 100644 --- a/lua/octo/commands.lua +++ b/lua/octo/commands.lua @@ -11,6 +11,15 @@ local config = require "octo.config" local colors = require "octo.ui.colors" local vim = vim +-- a global variable where command handlers can access the details of the last +-- command ran. +-- +-- this came into existence since some commands like "comment add" need to +-- understand the line range the comment should be created on. +-- this is problematic without the command options as you exit visual mode when +-- enterting the command line. +OctoLastCmdOpts = nil + local M = {} local get_current_buffer = function() @@ -32,7 +41,9 @@ end function M.setup() vim.api.nvim_create_user_command("Octo", function(opts) + OctoLastCmdOpts = opts require("octo.commands").octo(unpack(opts.fargs)) + OctoLastCmdOpts = nil end, { complete = require("octo.completion").octo_command_complete, nargs = "*", range = true }) local conf = config.values @@ -536,6 +547,7 @@ function M.octo(object, action, ...) utils.error(action and "Incorrect action: " .. action or "No action specified") return end + res = pcall(a, ...) if not res then utils.error(action and "Failed action: " .. action) diff --git a/lua/octo/reviews/init.lua b/lua/octo/reviews/init.lua index 0583b6bf..5a203e53 100644 --- a/lua/octo/reviews/init.lua +++ b/lua/octo/reviews/init.lua @@ -329,8 +329,15 @@ function Review:add_comment(isSuggestion) return end - -- get visual selected line range + -- get visual selected line range, used if coming from a keymap where current + -- mode can be evaluated. local line1, line2 = utils.get_lines_from_context "visual" + -- if we came from the command line the command options will provide line + -- range + if OctoLastCmdOpts ~= nil then + line1 = OctoLastCmdOpts.line1 + line2 = OctoLastCmdOpts.line2 + end local comment_ranges, current_bufnr if split == "RIGHT" then diff --git a/lua/octo/utils.lua b/lua/octo/utils.lua index 494cc3fb..a578dfd2 100644 --- a/lua/octo/utils.lua +++ b/lua/octo/utils.lua @@ -1642,8 +1642,8 @@ function M.get_lines_from_context(calling_context) line_number_start = vim.fn.line "." line_number_end = line_number_start elseif calling_context == "visual" then - line_number_start = vim.fn.line "'<" - line_number_end = vim.fn.line "'>" + line_number_start = vim.fn.line "v" + line_number_end = vim.fn.line "." elseif calling_context == "motion" then line_number_start = vim.fn.getpos("'[")[2] line_number_end = vim.fn.getpos("']")[2]