Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(neovim): add configuration guide for Neovim as LSP client #270

Merged
merged 17 commits into from
Mar 3, 2025

Conversation

PMassicotte
Copy link
Contributor

Introduce a new documentation file for configuring Neovim as a Language Server Protocol (LSP) client using nvim-lspconfig and conform.nvim. This guide provides step-by-step instructions for setting up Air as an LSP client and enabling automatic formatting on save. Update the main editors documentation to include a link to the new Neovim guide, expanding the list of supported editors.

@PMassicotte
Copy link
Contributor Author

Did that rapidly, please let me know if I missed something. This configuration has worked fine for me for the past few days.

Introduce a new documentation file for configuring Neovim as a
Language Server Protocol (LSP) client using nvim-lspconfig and
conform.nvim. This guide provides step-by-step instructions for
setting up Air as an LSP client and enabling automatic formatting
on save. Update the main editors documentation to include a link
to the new Neovim guide, expanding the list of supported editors.
@m-muecke
Copy link

m-muecke commented Feb 27, 2025

Did that rapidly, please let me know if I missed something. This configuration has worked fine for me for the past few days.

Nice! Since air is already merged in nvim-lspconfig one doesn't have to create a custom setup and the following is sufficient:

require("lspconfig").air.setup({})

and maybe adding a guide on using air and other language servers such as r-language-server to disable the formatting.

@PMassicotte
Copy link
Contributor Author

Nice! The config for using nvim-lspconfig is missing and a guide for disabling the formatting compatibility of r-language-server when both are in use. Hence, the setup for lspconfig is just the following:

require("lspconfig").air.setup({})

Thank you for your inputs 👍

Do you mean to add this after the require("lspconfig.configs").air block?

require("lspconfig").air.setup({})

@PMassicotte
Copy link
Contributor Author

Let me try just calling setup.

@PMassicotte
Copy link
Contributor Author

You

Nice! Since air is already merged in nvim-lspconfig one doesn't have to create a custom setup and the following is sufficient:

require("lspconfig").air.setup({})

You are absolutely right. I will modify accordingly.

Copy link
Contributor

@TymekDev TymekDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together! I have added some comments with my feedback.

To enable automatic formatting on save, add the following to your `nvim/after/plugin/lsp.lua` (or other appropriate location):

```lua
vim.api.nvim_create_autocmd("BufWritePre", {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it makes sense to provide this autocmd? I'd expect everyone to already have something like this in their config.

However, for the completeness (e.g. for Neovim newcomers) it might make sense to keep it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth to consider: using ftplugin.

Putting the below command in either ftplugin/r.lua or after/ftplugin/r.lua would have a roughly the same effect. I supposed it's a style preference of using pattern vs. filetypes.

vim.api.nvim_create_autocmd("BufWritePre", {
  buffer = 0,
  callback = function()
    vim.lsp.buf.format()
  end,
})

Copy link
Contributor Author

@PMassicotte PMassicotte Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth to consider: using ftplugin.

Putting the below command in either ftplugin/r.lua or after/ftplugin/r.lua would have a roughly the same effect. I supposed it's a style preference of using pattern vs. filetypes.

vim.api.nvim_create_autocmd("BufWritePre", {
  buffer = 0,
  callback = function()
    vim.lsp.buf.format()
  end,
})

I think you are right, either are fine. Maybe we can propose both solution/approach. Using the filter might be better for those that also have rlanguageserver to be specific on which one to use?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When responding to another comment, I just realized that on_attach seems to make the all-in-one setup() call:

require("lspconfig").air.setup({
  on_attach = function(_, bufnr)
    vim.api.nvim_create_autocmd("BufWritePre", {
      buffer = bufnr,
      callback = function()
        vim.lsp.buf.format()
      end,
    })
  end,
})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will use your solution, it makes sens and likely easier to configure for neovim newcomer. Thank you.

Comment on lines 46 to 62
return {
"stevearc/conform.nvim",
enabled = true,
config = function()
local conform = require("conform")

conform.setup({
notify_on_error = true,
format_on_save = {
lsp_fallback = true,
},
formatters_by_ft = {
r = { "air" },
},
})
end,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a lazy.nvim-specific setup. I'd suggest using a generic setup (example below) and point to conform's README for a way to install the plugin.

require("conform").setup({
  formatters_by_ft = {
    r = { "air" },
  },
})

What about filetypes for R markdown and Quatro?

Copy link
Contributor Author

@PMassicotte PMassicotte Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently not supported.

#265


## conform.nvim configuration

Air can be configured as a formatter plugin via [conform.nvim](https://github.com/stevearc/conform.nvim). This allows you to format R code with Air inside code chunks in Quarto and RMarkdown documents. It can be configured by adding the following to your `nvim/lua/plugins/conform.lua`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Air can be configured as a formatter plugin via [conform.nvim](https://github.com/stevearc/conform.nvim). This allows you to format R code with Air inside code chunks in Quarto and RMarkdown documents. It can be configured by adding the following to your `nvim/lua/plugins/conform.lua`:
Air can be used as a formatter via [conform.nvim](https://github.com/stevearc/conform.nvim). This allows using Air to format R code inside code chunks in Quarto and RMarkdown documents. It can be configured by adding the following to your configuration:

This allows you to format R code with Air inside code chunks in Quarto and RMarkdown documents.

Is this an out-of-the-box functionality or does one need to configure tree-sitter injections? 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is out of the box, my conform config is pretty simple.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TymekDev and @PMassicotte can you please double check that Air works in various Quarto and RMarkdown documents? I have my doubts because I went looking in conform and could not find any specific Quarto support for LSP/formatting passthrough.

If it does seem to be working, I'd love to know what I missed so I can study how it works on the conform side

Copy link

@m-muecke m-muecke Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TymekDev and @PMassicotte can you please double check that Air works in various Quarto and RMarkdown documents? I have my doubts because I went looking in conform and could not find any specific Quarto support for LSP/formatting passthrough.

If it does seem to be working, I'd love to know what I missed so I can study how it works on the conform side

@DavisVaughan conform.nvim supports injected language formatting this is probably what's meant here, see the following: https://github.com/stevearc/conform.nvim/blob/master/doc/advanced_topics.md#injected-language-formatting-code-blocks. I can confirm that it works with Rmarkdown and Quarto files, I'm guessing since Rmarkdown and Quarto inherit from markdown treesitter it works "out of the box".

PMassicotte and others added 4 commits February 27, 2025 16:40
Co-authored-by: Tymoteusz Makowski <[email protected]>
Co-authored-by: Tymoteusz Makowski <[email protected]>
Tx!

Co-authored-by: Tymoteusz Makowski <[email protected]>
…add link to documentation for further guidance
PMassicotte and others added 5 commits February 28, 2025 06:45
@PMassicotte
Copy link
Contributor Author

I think I have managed to include everyone's comment. Thank you very much.

@lionel-
Copy link
Collaborator

lionel- commented Feb 28, 2025

One question, is it possible to use Air as a language server in general and still configure conform to use it for Quarto documents at the same time?

@lionel-
Copy link
Collaborator

lionel- commented Feb 28, 2025

I think this bit from their README indicates that both can be used simultaneously:

Fixes bad-behaving LSP formatters - Some LSP servers are lazy and simply replace the entire buffer, leading to the problems mentioned above. Conform hooks into the LSP handler and turns these responses into proper piecewise changes.

@PMassicotte
Copy link
Contributor Author

One question, is it possible to use Air as a language server in general and still configure conform to use it for Quarto documents at the same time?

Yes, it can be used for both, R files with the lsp-config and quarto/rmd when adding the conform configuration.

Comment on lines +22 to +31
require("lspconfig").air.setup({
on_attach = function(_, bufnr)
vim.api.nvim_create_autocmd("BufWritePre", {
buffer = bufnr,
callback = function()
vim.lsp.buf.format()
end,
})
end,
})
Copy link
Collaborator

@DavisVaughan DavisVaughan Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can someone help me understand why the on_attach is required?

I'm comparing to ruff, for example:
https://docs.astral.sh/ruff/editors/setup/#neovim

That does not have this on_attach hook to enable the BufWritePre pre-write hook. I would have thought that just setting up Air as an LSP would have activated something like this on its own.

Is Ruff's documentation missing something? Is this BufWritePre overkill? Or am I missing something else?

(I'll take over doc changes from here on, so please just leave a comment rather than pushing)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, it's not reuiqred. However, without it formatting will work only on demand (by manually running vim.lsp.buf.format()). Adding this particular on_attach effectively enables formatting on save.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so IIUC its like editor.formatOnSave in VS Code. Without that, you can invoke Format Document to tell the LSP to format your document, but with that setting set to true it will do so automatically on every save.

I guess in ruff they just didn't think to say that part.

But makes sense to me thanks!

@DavisVaughan DavisVaughan merged commit cc7f6bc into posit-dev:main Mar 3, 2025
@DavisVaughan
Copy link
Collaborator

Thanks @PMassicotte, @TymekDev, and @m-muecke!

@PMassicotte
Copy link
Contributor Author

Thanks @PMassicotte, @TymekDev, and @m-muecke!

Thank you everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants