diff --git a/lua/jumpy/prompt.lua b/lua/jumpy/prompt.lua index 6a3e7ca..12357ed 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,16 @@ 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 ") + + 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) M._set_submit_keymap() M._setup_completions(state.buf) @@ -173,7 +181,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 @@ -242,6 +253,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) diff --git a/lua/jumpy/utils.lua b/lua/jumpy/utils.lua new file mode 100644 index 0000000..120f44b --- /dev/null +++ b/lua/jumpy/utils.lua @@ -0,0 +1,32 @@ +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 end_line = end_pos[2] + + if start_line > end_line or (start_line == end_line) then + start_line, end_line = end_line, start_line + end + + local lines = vim.api.nvim_buf_get_lines(bufnr, start_line - 1, end_line, false) + + if #lines == 0 then + return nil + end + + return { + text = table.concat(lines, "\n"), + start_line = start_line, + end_line = end_line, + mode = mode, + } +end + +return M