R-nvim / R.nvim

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

issues with formatting #225

Closed idavydov closed 1 week ago

idavydov commented 2 weeks ago

I'm having issues with formatting .Rmd/.qmd files. When I call :RFormat I get the following error:

[Server] Unknown command received: [95]
│_samples(remove_empty_locations = TRUE) |>^T
│group_by(patient, timepoint) |>^T
│filter(n_distinct(batch) > 1) |>^T
...

The last portion represents the contents of the .Rmd/.qmd file.

idavydov commented 2 weeks ago

Here's a .qmd file which reproducibly leads to the error for me. If I minimize it further the error either disappears or changes to a different one.

````md ```{r} library(tidyverse) library(designit) ``` ```{r} samples_tab_pre <- cross_join( tibble(patient = str_c("P", 1:11)), tibble(timepoint = str_c("T", 1:2)) ) samples_tab <- samples_tab_pre |> bind_rows( sample_n(samples_tab_pre, size = 10) ) |> arrange(timepoint) |> mutate(sam_id = row_number()) ``` ```{r} bc <- BatchContainer$new( dimensions = list( batch = 4, location = 10 ) ) |> assign_in_order( samples_tab ) ``` ```{r} bc$get_samples() |> ggplot() + aes(batch, fill = timepoint) + geom_bar() ``` ```{r} bc1 <- optimize_design( bc, scoring = osat_score_generator( batch_vars = "batch", feature_vars = "timepoint" ), max_iter = 100 ) ``` ```{r} bc1$get_samples() |> ggplot() + aes(batch, fill = timepoint) + geom_bar() ``` Find cases when samples from the sampe patient are in different batches: ```{r} bc1$get_samples(remove_empty_locations = TRUE) |> group_by(patient, timepoint) |> filter(n_distinct(batch) > 1) |> arrange(patient) ``` ````
idavydov commented 2 weeks ago

If I run styler::style_file("err1.qmd") explicitly, the file is not changed:

Styling  1  files:
 err1.qmd ✔ 
────────────────────────────────────────
Status  Count   Legend 
✔       1       File unchanged.
ℹ       0       File changed.
✖       0       Styling threw an error.
────────────────────────────────────────
jalvesaq commented 2 weeks ago

We always call style_text while we should call style_text to format a selection of lines and save the buffer and, then, call style_file to format the whole file.

jalvesaq commented 2 weeks ago

Could you, please, try https://github.com/R-nvim/R.nvim/pull/226 ?

idavydov commented 2 weeks ago

this seem to fix it, thanks! the only thing, I get console output and no new prompt after that. I think either the output should be suppressed or new prompt should be outputted after styling.

> Styling  1  files:
 .../err1.qmd ✔ 
────────────────────────────────────────
Status  Count   Legend 
✔       1       File unchanged.
ℹ       0       File changed.
✖       0       Styling threw an error.
────────────────────────────────────────
jalvesaq commented 2 weeks ago

Running style_file() quietly now. Please, do this before trying the branch again because I didn't increase nvimcom version number:

echo 'remove.packages("nvimcom")' | R
jalvesaq commented 2 weeks ago

The functions of the formatR package are not working well with R.nvim. Since styler has the same functionality, I would rather remove formatR as an option than fix its integration with R.nvim. Does anyone know of any advantages of formatR over styler?

idavydov commented 2 weeks ago

thanks a lot, this fixed it for me.

I never used formatR, so cannot contribute to the styler vs formatR discussion.

PMassicotte commented 2 weeks ago

I am using conform to format all my code.

jalvesaq commented 2 weeks ago

conform.nvim depends on the languageserver which depends on styler. So, perhaps we should simply remove the :RFormat command from R.nvim and add a page to the Wiki with tips on getting a complete IDE for R.

jalvesaq commented 2 weeks ago

Does conform.nvim work well with Quarto documents?

PMassicotte commented 2 weeks ago

Does conform.nvim work well with Quarto documents?

Yes very good. Here is my config.

return { -- Autoformat
    "stevearc/conform.nvim",
    enabled = true,
    config = function()
        local conform = require("conform")

        conform.setup({
            notify_on_error = true,
            format_on_save = {
                timeout_ms = 2000,
                lsp_fallback = true,
            },
            formatters_by_ft = {
                css = { "prettier" },
                scss = { "prettier" },
                lua = { "mystylua" },
                python = { "isort", "black" },
                quarto = { "injected", "prettier" },
                rmd = { "injected", "prettier" },
                bash = { "shfmt" },
                r = { "mystyler" },
                latex = { "latexindent" },
                sql = { "sqlformatter" },
                markdown = { "prettier" },
                toml = { "taplo" },
                yaml = { "prettier" },
                html = { "prettier" },
            },
            formatters = {
                mystylua = {
                    command = "stylua",
                    args = {
                        "--indent-type",
                        "Spaces",
                        "--indent-width",
                        "4",
                        "-",
                        "--quote-style",
                        "AutoPreferDouble",
                    },
                },
                mystyler = {
                    command = "R",
                    args = { "-s", "-e", "styler::style_file(commandArgs(TRUE)[1])", "--args", "$FILENAME" },
                    stdin = false,
                },
                sqlformatter = {
                    command = "sql-formatter",
                    args = {
                        "-l=bigquery",
                        '--config={"tabWidth": 2, "keywordCase":"upper", "expressionWidth":80, "linesBetweenQueries":2}',
                    },
                },
            },
        })

        -- Customize the "injected" formatter
        conform.formatters.injected = {
            options = {
                ignore_errors = false,
                lang_to_ext = {
                    bash = "sh",
                    c_sharp = "cs",
                    elixir = "exs",
                    javascript = "js",
                    julia = "jl",
                    latex = "tex",
                    markdown = "md",
                    python = "py",
                    ruby = "rb",
                    rust = "rs",
                    teal = "tl",
                    r = "r",
                    typescript = "ts",
                },
                lang_to_formatters = {},
            },
        }

        require("conform").formatters.prettier = {
            options = {
                ft_parsers = {
                    quarto = "markdown",
                    rmd = "markdown",
                },
            },
        }
    end,
}
jalvesaq commented 1 week ago

thanks a lot, this fixed it for me.

Thanks for the feedback! The pull request was merged.