Nvim-R
Nvim-R copied to clipboard
Getting knitr::read_chunk to work with Nvim-R
I've started to use the knitr::read_chunk
function to separate out the logic from my Rmarkdown files (see https://yihui.name/knitr/demo/externalization/).
For instance, consider the following test.Rmd
file:
---
title: "Testing the read_chunk with Nvim-R"
---
```{r setup, message = FALSE, warning = FALSE}
library("knitr")
read_chunk("test_chunk.R")
```
```{r test-chunk}
```
My test_chunk.R
file then has the following contents:
# ---- test-chunk ----
dplyr::filter(mtcars, cyl == 4)
When rendering the test.Rmd
file, the logic in test_chunk.R
gets read but not evaluated. It only gets evaluated when there is a chunk label that matches a label in the test_chunk.R
.
It doesn't seem Nvim-R is able to work with read_chunks
. Specifically, it would be nice to go over the test-chunk
and be able to use one of the send commands (e.g. \cc
). It would then be able to read in the logic for that chunk and run it.
What is the advantage of using this system instead of source()
at the appropriate place?
related:
@yihui (the author of knitr
) wrote:
I think it is legitimate to simply source() the script. There is no need to read_chunk().
What is the advantage of using this system instead of source() at the appropriate place?
The advantage becomes more apparent when you have multiple logic chunks in your test_chunk.R
. For instance:
# ---- test-chunk-1 ----
dplyr::filter(mtcars, cyl == 4)
# ---- test-chunk-2 ----
dplyr::filter(mtcars, cyl == 6)
# ---- test-chunk-3 ----
dplyr::filter(mtcars, cyl == 8)
These can then be evaluated at different times in your Rmarkdown. For instance:
---
title: "Testing the read_chunk with Nvim-R"
---
```{r setup, message = FALSE, warning = FALSE}
library("knitr")
read_chunk("test_chunk.R")
```
```{r test-chunk-1}
```
Some description of the results from test-chunk-1
```{r test-chunk-2}
```
Some description of the results from test-chunk-2
```{r test-chunk-3}
```
Some description of the results from test-chunk-3
It's helpful when you have long documents and don't want too much code to be in the document itself. You could put each of those chunk logics in a separate file and then source the file in the chunk when you need it, but IMO that becomes confusing to track all the files.
related:
@yihui (the author of
knitr
) wrote:I think it is legitimate to simply source() the script. There is no need to read_chunk().
If I understand correctly, I think that quote might be taken out of context. Yihui was responding to the commenter's question about whether it was legitimate to use source
rather than read_chunk
in their situation. He was saying it was in that scenario. He wasn't suggesting that read_chunk
has no use.
He was saying it was in that scenario. He wasn't suggesting that
read_chunk
has no use.
That's right.
So, a algorithm to implement the requested feature would be:
- The user types
<LocalLeader>cc
when the cursor is over a chunk. - If the chunk is empty, Nvim-R gets its label and asks R to execute the corresponding code from knitr memory.
Is that correct? Is there a knitr command that gets a label as input and either returns the code to be run or directly runs the code?
@jalvesaq:
Is there a knitr command that gets a label as input and either returns the code to be run or directly runs the code?
Seem like knitr:::knit_code$get()
is what you are looking for:
#' The code manager to manage code in all chunks
#'
#' This object provides methods to manage code (as character vectors) in all
#' chunks in \pkg{knitr} source documents. For example,
#' \code{knitr::knit_code$get()} returns a named list of all code chunks (the
#' names are chunk labels), and \code{knitr::knit_code$get('foo')} returns the
#' character vector of the code in the chunk with the label \code{foo}.
#' @note The methods on this object include the \code{set()} method (i.e., you
#' could do something like \code{knitr::knit_code$set(foo = "'my precious new
#' code'")}), but we recommend that you do not use this method to modify the
#' content of code chunks, unless you are
#' \href{https://emitanaka.rbind.io/post/knitr-knitr-code/}{as creative as Emi
#' Tanaka} and know what you are doing.
(see https://github.com/yihui/knitr/blob/7660d599c32168921ab5a89187d3636cad0e418d/R/parser.R#L44-L56)
So, a algorithm to implement the requested feature would be:
- The user types <LocalLeader>cc when the cursor is over a chunk.
- If the chunk is empty, Nvim-R gets its label and asks R to execute the corresponding code from knitr memory.
Is that correct?
That would be a sensible implementation of it.