R-nvim / R.nvim

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

Can not get arguments completion use `devtools::load_all` of functions which are not export in NAMESPACE #147

Open shaman-yellow opened 2 weeks ago

shaman-yellow commented 2 weeks ago

This may not be a issue, but is a different feature from Nvim-R. devtools::load_all has parameter of export_all, theoretically the functions were exported, but I can't get argument completion unless I specify in NAMESPACE that the function is exported. For me, since my package may not be shared with others, I will not specifically indicate in NAMESPACE that the function needs to be exported. devtools::load_all makes all these functions exported. This is very convenient.

jalvesaq commented 2 weeks ago

The completion data includes only functions from libraries listed by the search() command: https://github.com/R-nvim/R.nvim/blob/dc4eb50e4fd11b342d89b50b66b7dff4166f3673/nvimcom/src/nvimcom.c#L816

I don't use devtools. So, you or someone else would have to do a pull request adding the ability to list functions loaded by devtools::load_all() and other people from the R-nvim organization should approve the pull request.

shaman-yellow commented 2 weeks ago

But Nvim-R does. What's the difference? I did not notice a significant difference between <R.nvim/nvimcom/src/nvimcom.c> with <Nvim-R/nvimcom/src/nvimcom.c>

jalvesaq commented 2 weeks ago

I don't know. Could you describe simple steps that I could copy and paste to see what happens? Anyway, I will not have free time in the next few days.

jalvesaq commented 2 weeks ago

Just a random idea: if you have installed your package in the past as a normal library, Nvim-R might have built the necessary cache files at ~/.cache/Nvim-R...

shaman-yellow commented 2 weeks ago

We can use usethis::create_package to create a test package, then load it by devtools::load_all:

usethis::create_package("~/ATestPackage")
writeLines("ATestFun <- function(x) {\n print('Test this') \n}", "~/ATestPackage/R/test.R")
list.files("~/ATestPackage/", recursive = T)
# [1] "DESCRIPTION" "NAMESPACE"   "R/test.R"   

# The `NAMESPACE` is empty
readLines("~/ATestPackage/NAMESPACE")
# [1] "# Generated by roxygen2: do not edit by hand"
# [2] ""                                            

# Now we load it
devtools::load_all("~/ATestPackage")

# The `ATestPackage` exists in `search()` results
search()[grep("ATestPackage", search())]
# [1] "package:ATestPackage"

# we can directly call it without prefix `ATestPackage::`
ATestFun()
# [1] "Test this"

However, I can't get completion with R.nvim, but Nvim-R does.

Next we try to build a complete package.

writeLines(
  c("#' This is title for R help of this function",
    "#' ",
    "#' This is description.",
    "#' ",
    "#' @param x this is a test parameter",
    "#' @export",
    "ATestFun <- function(x) {\n print('Test this') \n}"),
  "~/ATestPackage/R/test.R")
roxygen2::roxygenize("~/ATestPackage")
devtools::load_all("~/ATestPackage")
# It still can't get completion

devtools::install_local("~/ATestPackage")
library(ATestPackage)
# Oh, It still can't get completion
ATestFun()
shaman-yellow commented 2 weeks ago

If we start a new R, without executing devtools::load_all, we directly:

library(ATestPackage)
# completion work fine
ATestFun()
shaman-yellow commented 2 weeks ago

Just a random idea: if you have installed your package in the past as a normal library, Nvim-R might have built the necessary cache files at ~/.cache/Nvim-R...

With Nvim-R, I manualy delete ~/.cache/Nvim-R/..., Nvim-R still works fine, it recreates the file.

jalvesaq commented 2 weeks ago

:RDebugInfo shows this:

stderr of last completion data building:
Warning in utils::packageDescription(p) : no package 'ATestPackage' was found
Error in utils::packageDescription(p)$Version:
$ operator is invalid for atomic vectorsCalls: <Anonymous>Execution halted

It seems that the package is not available yet when R.nvim tries to build its completion data.

jalvesaq commented 2 weeks ago

:RDebugInfo shows the same error in both Nvim-R and Neovim. And the completion doesn't work in any of them.

jalvesaq commented 2 weeks ago

Note: I tested Nvim-R in Vim (9.1.377) and R.nvim in Neovim (0.11.0-dev).

jalvesaq commented 2 weeks ago

With the "complete" package, there is an attempt of completion right after devtools::load_all(), but the result is this warning (which really is an error):

Incomplete string received. Expected 129309 bytes; received 129308.

Perhaps you don't see the warning in Insert mode, but you can see it with the :messages command (or immediately with the 'rcarriga/nvim-notify' plugin).

jalvesaq commented 2 weeks ago

I changed the version number to 0.0.0.9002 to force the rebuilding of completion data:

image

shaman-yellow commented 2 weeks ago

Strangely, my Nvim-R works fine.

Screenshot from 2024-06-16 10-28-06

before_rns.R stdout: (empty)                                                            
stderr of last completion data building:                                                         

before_rns.R stderr: (empty)                                                                     
Time:                                                                                            
  global setup: 0.002919363                                                                      
  before_rns.R (async): 0.142355214                                                              
  check health (async): 0.000571862                                                              
  unix setup: 1.8205e-05                                                                         
nvimcom info:                                                                                    
  home: /home/echo/R/x86_64-pc-linux-gnu-library/4.2/nvimcom                                     
  version: 0.9.42                                                                                
  Rversion: 4.2.1
NVIM v0.10.0-dev
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Run "nvim -V1 -v" for more info
jalvesaq commented 2 weeks ago

Trying again... It only worked because I have installed the package from the terminal:

R CMD INSTALL ~/ATestPackage

It doesn't work if I use devtools.

jalvesaq commented 2 weeks ago

R.nvim runs an external R instance to build the completion data. So, the package must be installed as a normal package to be found.

shaman-yellow commented 2 weeks ago

If this is not available in R.nvim, I will just use Nvim-R from now on.

jalvesaq commented 2 weeks ago

This seems to work:

devtools::install_local("~/ATestPackage")
library(ATestPackage)

I removed the package from R, and manually removed its files from ~/.cache/R.nvim. The completion worked after the two commands above.

jalvesaq commented 2 weeks ago

I can't understand why Nvim-R works with Neovim (I tested it only with Vim and it doesn't work) because since 2021 the cache files are built by another R instance run by the nclientserver. Anyway, the goal of using another R instance to build the cache files is to avoid an extra delay when loading a new library version for the first time, and I don't plan to revert this procedure to the previous one (cache files built by the currently running R instance).

shaman-yellow commented 2 weeks ago

Do you mean that starting a new R example will load the same packages in that example using library or require as in the original R? So, packages loaded using devtools::load_all will not be found in the new R example.

shaman-yellow commented 2 weeks ago

Is it possible that it has something to do with other vim plugins, like cmp-nvim-r? I switch between R.nvim and Nvim-R in the following way.

if (0)
    let g:use_old_nvim_r = 0
    Plug 'R-nvim/R.nvim', {'do': ':TSUpdate'}
    Plug 'R-nvim/cmp-r'
    Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
  else
    let g:use_old_nvim_r = 1
    Plug 'jalvesaq/Nvim-R'
    Plug 'jalvesaq/cmp-nvim-r'
  endif
jalvesaq commented 2 weeks ago

cmp-r and cmp-nvim-r are only clients of rnvimserver. They do not influence the issue.

Packages loaded using devtools::load_all will be loaded in R memory, but not saved in any of R's library directories. For example, if you start two R instances in different terminal emulators, and load a package in one of them, it will not be available on the other (it will not be on the search() list). Both Nvim-R and R.nvim run another R instance in the background to build the cache data. It's not the R that you are seeing below (or beside) the script that you are editing that builds the cache files.

However, if you install a package (with either R CMD INSTALL or devtools::install_local), the package will be saved in an R library directory. Consequentely, utils::packageDescription() will find the package, and nvimcom (in the R running in the background) will be able to build the cache files for completion only if the package was installed.