R-nvim / R.nvim

Neovim plugin to edit R files
GNU General Public License v3.0
129 stars 15 forks source link

Fix single line Shift+V send #59

Closed wklimowicz closed 4 months ago

wklimowicz commented 4 months ago

Doing a line-wise visual Shift+V and RSendSelection (or :lua require('r.send').selection(false)) on a single line is currently broken. I think this is because it gets caught into this if statement, which does + 1 to the start and end column position to align it on line 381:

https://github.com/R-nvim/R.nvim/blob/c0dc42b1b197476e2ff9c85e68dbf5daf598d1d2/lua/r/send.lua#L379-L386

The problem comes because in line-wise visual mode the column index of end_pos is set to $2^{31} -1$, and you probably get some sort of overflow error when you add 1.

I'm not convinced my solution is best since it requires another if statement, but I thought it's better than nesting inside the if statement above. Good if someone could test this too and see if there's a neater solution.

jalvesaq commented 4 months ago

Thank you for reporting the bug and suggesting a fix!

I tested the send selection with this "code":

123456
234567
345678
456789

But I didn't consider the possibility of selecting just one line with <Shift-V>.

With the change below, we can fix the bug by reducing the number of lines instead of increasing it:

diff --git a/lua/r/send.lua b/lua/r/send.lua
index 27e37cc..f100e2b 100644
--- a/lua/r/send.lua
+++ b/lua/r/send.lua
@@ -377,15 +377,6 @@ M.selection = function(m)
     local end_pos = vim.api.nvim_buf_get_mark(0, ">")
     local lines = vim.api.nvim_buf_get_lines(0, start_pos[1] - 1, end_pos[1], true)

-    if start_pos[1] == end_pos[1] then
-        local line = lines[1]
-        line = string.sub(line, start_pos[2] + 1, end_pos[2] + 1)
-        if vim.o.filetype == "r" then line = cursor.clean_oxygen_line(line) end
-        local ok = M.cmd(line)
-        if ok and m == true then cursor.move_next_line() end
-        return
-    end
-
     local vmode = vim.fn.visualmode()
     if vmode == "\022" then
         -- "\022" is <C-V>
@@ -400,9 +391,13 @@ M.selection = function(m)
             lines[k] = string.sub(lines[k], cj, ck)
         end
     elseif vmode == "v" then
-        lines[1] = string.sub(lines[1], start_pos[2] + 1, -1)
-        local llen = #lines
-        lines[llen] = string.sub(lines[llen], 1, end_pos[2] + 1)
+        if start_pos[1] == end_pos[1] then
+            lines[1] = string.sub(lines[1], start_pos[2] + 1, end_pos[2] + 1)
+        else
+            lines[1] = string.sub(lines[1], start_pos[2] + 1, -1)
+            local llen = #lines
+            lines[llen] = string.sub(lines[llen], 1, end_pos[2] + 1)
+        end
     end

     if vim.o.filetype == "r" then
jalvesaq commented 4 months ago

Could you update your pull request?

jalvesaq commented 4 months ago

Thank you!

wklimowicz commented 4 months ago

Fantastic, I defer to your knowledge and lua skills. Thank you!

akthe-at commented 4 months ago

Thank you all, I ran into this bug but I couldn't figure out how to reproduce it because I didn't realize it was only happening on single line Shift +V send...