R-nvim / R.nvim

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

Has function of `<Leader>l` and `<Leader>d` been changed? #175

Open joihci opened 3 days ago

joihci commented 3 days ago

When I press <Leader>l or <Leader>d inside a function body the whole function is sent to terminal instead of the line under cursor. When cursor is outside of a function these keybinds work as expected. However using the motion command inside a function works i.e. <Leader>ml sends the line under cursor, <Leader>md does nothing.

Is this a bug or has the function of <Leader>l and <Leader>d been changed?

See behaviour on provided screenshot: image

Info:

NVIM v0.10.0
Build type: Release
LuaJIT 2.1.1713484068

OS: Ubuntu 22.04.4 LTS

Using minimal init.vim for provided example in screenshot:

call plug#begin(stdpath("data")."/plugged")
Plug 'R-nvim/R.nvim'
Plug 'nvim-treesitter/nvim-treesitter', { 'do': ':TSUpdate' }
call plug#end()

lua require("r").setup({ pipe_keymap = "<M-,>" })
let mapleader="\<Space>"
let maplocalleader="\<Space>"
lua <<EOF
require("nvim-treesitter.configs").setup {
  ensure_installed = "all", -- one of "all",
  highlight = {
    enable = true,
    additional_vim_regex_highlighting = false,
  },
  playground = {
    enable = true,
    disable = {},
    updatetime = 25,
    persist_queries = false,
    keybindings = {
      toggle_query_editor = "o",
      toggle_hl_groups = "i",
      toggle_injected_languages = "t",
      toggle_anonymous_nodes = "a",
      toggle_language_display = "I",
      focus_language = "f",
      unfocus_language = "F",
      update = "R",
      goto_node = "<cr>",
      show_help = "?",
    },
  }
}
EOF
PMassicotte commented 3 days ago

Probably related to changes in treesitter-r.

PMassicotte commented 3 days ago

I might be wrong, I do not use this in my workflow. It used to send the current line when you were inside a functon?

joihci commented 3 days ago

Yes, it's convenient to execute a line in a function body for quick debugging and besides there is a keybind for sending the current function under cursor (shouldn't matter whether cursor is in body or on definition: <Leader>fc.

But now when I press <Leader>fc within a function I get an error (had not tried it before creating this issue): image

PMassicotte commented 3 days ago

Ok, let me look at it.

PMassicotte commented 3 days ago

Can you try this branch and see if it fixes the problem: https://github.com/R-nvim/R.nvim/tree/fix-send-function-treesitter-r

joihci commented 3 days ago

On branch fix-send-function-treesitter: <Leader>d and <Leader>l still send the whole function instead of current line. <Leader>fc does not give an error but sends 3 copies of the function to console.

PMassicotte commented 3 days ago

Tight on time today, I will take time this weekend.

joihci commented 3 days ago

I'm going on vacation but bringing my laptop with me so I'll try to check in if you need any testing done.

PMassicotte commented 3 days ago

I fixed the <localleader>fc, it now send the function only once. However, I think that sending line it supposed to send the whole expression it is currently in.

--- Get the full expression the cursor is currently on
---@param txt string The text for the line the cursor is currently on
---@param row number The row the cursor is currently on
---@return table, number
local function get_code_to_send(txt, row)
    if not config.parenblock then return {}, row end

    local last_line = vim.api.nvim_buf_line_count(0)
    local lines = {}
    local send_insignificant_lines = false

    -- Find the first non-blank row/column after the cursor ---------------
    while is_insignificant(txt) do
        if is_comment(txt) then send_insignificant_lines = true end
        if send_insignificant_lines then table.insert(lines, txt) end
        if row == last_line then return lines, row end
        row = row + 1
        txt = vim.fn.getline(row)
    end

    local col = txt:find("%S")

    -- Find the 'root' node for the current expression --------------------
    local n_lang = vim.o.filetype == "rnoweb" and "r" or nil
    local node = vim.treesitter.get_node({
        bufnr = 0,
        pos = { row - 1, col - 1 },
        lang = n_lang,
        -- Required for quarto/rmd/rnoweb; harmless for r.
        ignore_injections = false,
    })

    while node do
        local parent = node:parent()
        if parent and (parent:type() == "program" or parent:type() == "brace_list") then
            break
        end
        node = parent
    end

    if node then
        row = node:end_()
        table.insert(lines, vim.treesitter.get_node_text(node, 0))
    end

    return lines, row
end

For me, sending 1 line inside a function was always sending the whole context.

One thing you can do is to visually select the line and press enter (this is how I configured it on my side).