From f9e7040ef3ebc1a81b3455d770981175665998b9 Mon Sep 17 00:00:00 2001 From: Himanshu Sardana Date: Fri, 22 May 2026 08:48:26 +0530 Subject: [PATCH 1/5] chore: add get_visual_selection util --- lua/jumpy/utils.lua | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lua/jumpy/utils.lua diff --git a/lua/jumpy/utils.lua b/lua/jumpy/utils.lua new file mode 100644 index 0000000..0cf2b0b --- /dev/null +++ b/lua/jumpy/utils.lua @@ -0,0 +1,44 @@ +local M = {} + +function M.get_visual_selection(bufnr) + bufnr = bufnr or 0 + + local mode = vim.api.nvim_get_mode().mode + + local start_pos = vim.fn.getpos("v") + local end_pos = vim.fn.getpos(".") + + local start_line = start_pos[2] + local start_col = start_pos[3] + local end_line = end_pos[2] + local end_col = end_pos[3] + + if start_line > end_line or (start_line == end_line and start_col > end_col) then + start_line, end_line = end_line, start_line + start_col, end_col = end_col, start_col + end + + local lines = vim.api.nvim_buf_get_lines(bufnr, start_line - 1, end_line, false) + + if #lines == 0 then + return nil + end + + if mode == "v" then + lines[1] = lines[1]:sub(start_col) + lines[#lines] = lines[#lines]:sub(1, end_col) + elseif mode == "\22" then + for i, line in ipairs(lines) do + lines[i] = line:sub(start_col, end_col) + end + end + + return { + text = table.concat(lines, "\n"), + start_line = start_line, + end_line = end_line, + mode = mode, + } +end + +return M From 90b65690b129bbd95dbdbc4d395b94caaf4a5f1a Mon Sep 17 00:00:00 2001 From: Himanshu Sardana Date: Fri, 22 May 2026 09:56:01 +0530 Subject: [PATCH 2/5] feat: pass selection to request instead of entire file content --- lua/jumpy/prompt.lua | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lua/jumpy/prompt.lua b/lua/jumpy/prompt.lua index 6a3e7ca..7a5cdc8 100644 --- a/lua/jumpy/prompt.lua +++ b/lua/jumpy/prompt.lua @@ -1,6 +1,7 @@ local M = {} local context_tools = require("jumpy.context-tools") +local utils = require("jumpy.utils") local state = { win = nil, @@ -75,9 +76,21 @@ function M.open() return end + local mode = vim.api.nvim_get_mode().mode + local is_scoped = mode == "v" or mode == "V" or mode == "\22" + state.source_buf = vim.api.nvim_get_current_buf() state.reprompt_hunk_idx = nil - state.buf, state.win = create_float(" jumpy ") + + if is_scoped then + state.visual_selection = utils.get_visual_selection(state.source_buf) + else + state.visual_selection = nil + end + + local title = is_scoped and " jumpy (scoped) " or " jumpy " + + state.buf, state.win = create_float(title) M._set_submit_keymap() M._setup_completions(state.buf) @@ -173,7 +186,10 @@ function M._submit() end local source_buf = state.source_buf - local source_lines = vim.api.nvim_buf_get_lines(source_buf, 0, -1, false) + + local source_lines = state.visual_selection and vim.split(state.visual_selection.text, "\n", { plain = true }) + or vim.api.nvim_buf_get_lines(source_buf, 0, -1, false) + local filetype = vim.bo[source_buf].filetype local reprompt_idx = state.reprompt_hunk_idx From 5a8b846b975912179d977d59fb0e10f7d00d596d Mon Sep 17 00:00:00 2001 From: Himanshu Sardana Date: Fri, 22 May 2026 09:57:58 +0530 Subject: [PATCH 3/5] fix: relative hunk positioning --- lua/jumpy/prompt.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lua/jumpy/prompt.lua b/lua/jumpy/prompt.lua index 7a5cdc8..4499898 100644 --- a/lua/jumpy/prompt.lua +++ b/lua/jumpy/prompt.lua @@ -258,6 +258,13 @@ function M._submit() end local hunks = diff.compute(source_lines, proposed_lines) + if state.visual_selection then + local offset = state.visual_selection.start_line - 1 + + for _, hunk in ipairs(hunks) do + hunk.old_start = hunk.old_start + offset + end + end if #hunks == 0 then vim.notify("jumpy: no changes proposed", vim.log.levels.INFO) From 900e08efb520e320228277195bdaabcca91b55a0 Mon Sep 17 00:00:00 2001 From: Himanshu Sardana Date: Fri, 22 May 2026 10:44:13 +0530 Subject: [PATCH 4/5] chore: replace if with ternary --- lua/jumpy/prompt.lua | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lua/jumpy/prompt.lua b/lua/jumpy/prompt.lua index 4499898..12357ed 100644 --- a/lua/jumpy/prompt.lua +++ b/lua/jumpy/prompt.lua @@ -82,12 +82,7 @@ function M.open() state.source_buf = vim.api.nvim_get_current_buf() state.reprompt_hunk_idx = nil - if is_scoped then - state.visual_selection = utils.get_visual_selection(state.source_buf) - else - state.visual_selection = nil - end - + state.visual_selection = is_scoped and utils.get_visual_selection(state.source_buf) or nil local title = is_scoped and " jumpy (scoped) " or " jumpy " state.buf, state.win = create_float(title) From 7f5893624b38f72b0989aa08a725e037a932603d Mon Sep 17 00:00:00 2001 From: Himanshu Sardana Date: Fri, 22 May 2026 18:25:02 +0530 Subject: [PATCH 5/5] fix(utils): remove visual selection and visual block mode helpers fix(utils): remove unused variables fix(utils): remove start_col and end_col --- lua/jumpy/utils.lua | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lua/jumpy/utils.lua b/lua/jumpy/utils.lua index 0cf2b0b..120f44b 100644 --- a/lua/jumpy/utils.lua +++ b/lua/jumpy/utils.lua @@ -9,13 +9,10 @@ function M.get_visual_selection(bufnr) local end_pos = vim.fn.getpos(".") local start_line = start_pos[2] - local start_col = start_pos[3] local end_line = end_pos[2] - local end_col = end_pos[3] - if start_line > end_line or (start_line == end_line and start_col > end_col) then + if start_line > end_line or (start_line == end_line) then start_line, end_line = end_line, start_line - start_col, end_col = end_col, start_col end local lines = vim.api.nvim_buf_get_lines(bufnr, start_line - 1, end_line, false) @@ -24,15 +21,6 @@ function M.get_visual_selection(bufnr) return nil end - if mode == "v" then - lines[1] = lines[1]:sub(start_col) - lines[#lines] = lines[#lines]:sub(1, end_col) - elseif mode == "\22" then - for i, line in ipairs(lines) do - lines[i] = line:sub(start_col, end_col) - end - end - return { text = table.concat(lines, "\n"), start_line = start_line,