Introduction
Over the past years, R has been gaining popularity, bringing to life new tools to with ith it. Thanks to the amazing work by contributors implementing the Language Server Protocol for R and writing Visual Studio Code Extensions for R, the most popular development environment amongst developers across the world now has very strong support for R as well.
In this post, we will look at the
languageserversetup
package that aims to make the setup of the R Language Server robust and easy to use by installing it into a separate, independent library and adjusting R startup in a way that initializes the language server when relevant.
Contents
Visual Studio Code and R
According to the 2019 StackOverflow developer survey, Visual Studio Code is the most popular development environment across the board, with amazing support for many languages and extensions ranging from improved code editing to advanced version control support and Docker integration.
Until recently the support for R in Visual Studio Code was in my view not comprehensive enough to justify switching from other tools such as RStudio (Server) to using VS Code exclusively. This has changed with the work done by the team implementing the following 3 tools:
- The R extension for VS Code
- The R LSP Client extension for VS Code
- The languageserver package: An implementation of the Language Server Protocol for R
The features now include all that we need to work efficiently, including auto-complete, definition provider, code formatting, code linting, information on functions on hover, color provider, code sections and more.
If you are interested in more steps around the setup and the overview of features I recommend the Writing R in VSCode: A Fresh Start blogpost by Kun Ren. I also recommend that you follow Kun on Twitter if you are interested in the latest developments.
Setup considerations, issues, and tweaks: creating the languageserversetup
package
With my current team, we have almost fully embraced Visual Studio Code as an IDE for our work in R, which is especially great as the work is multi-language and multi-environment in nature and we can do our development in Scala, R and more, including implementing and testing Jenkins pipelines and designing Docker images without leaving VS Code.
Setting up for the team on multiple systems and platforms we have found the following interesting points which were my motivation to write a small R package, languageserversetup, that should make the installation and setup of the R language server as easy and painless as possible.
Managing package libraries
One of the specifics of R is that all extensions (packages) are installed into package libraries, be it the packages we develop and use for our applications or the tools we use mostly as means to make our development life easier. We can therefore often end in a situation where we need to use different versions of R packages for different purposes. For example, the languageserver
package currently needs R6 (>= 2.4.1)
, stringr (>= 1.4.0)
and more, in total it recursively requires 75 other R packages to be installed. When installing and running the package we can run into conflicting versions of what our current applications need versus what the languageserver
package requires to function properly.
Managing library paths
The second consideration, related to the first one is that if we simply install the language server into the default library with for instance install.packages
it will change the library to a state that is possibly not desired. We can also run into unexpected crashes, where the languageserver
will function properly for a time until one of the non-triggered dependencies with a hidden conflict gets triggered.
A solution - Complete library separation and smart initialization
One possible solution to the above issues is to:
Keep the package libraries of the
languageserver
and the other libraries that the user uses (perhaps apart from the main system library containing the base and recommended packages that come with the R installation itself) completely separated, including all non-base dependenciesInitialize that library only when the R process in question is triggered by the language server, otherwise, keep the process untouched and use the user libraries as usual
Solving it with 2 R commands - the languageserversetup
package
To make the above solution easily accessible, I have created a small R package called languageserversetup
that will do all the work for you. It can be installed from CRAN and it has no dependencies on other R packages:
install.packages("languageserversetup")
Now the entire setup has only 2 steps:
- Install the
languageserver
package and all of its dependencies into a separate independent library (Will ask for confirmation before taking action) using:
languageserversetup::languageserver_install()
- Add code to
.Rprofile
to automatically align the library paths for the language server functionality if the process is an instance of thelanguageserver
, otherwise, the R session will run as usual with library paths unaffected. This is achieved by running (will also ask for confirmation):
languageserversetup::languageserver_add_to_rprofile()
That’s it. Now you can enjoy the functionality without caring about the setup of libraries or any package version conflicts. Thanks to the full separation of libraries, the removal is as trivial as deleting the library directory.
In action with VS Code
Installing languageserversetup and using languageserver_install()
Initializing the functionality with languageserver_add_to_rprofile()
All done, now enjoy the awesomeness!
Technical details
If you are interested in more technical details,
- please visit the package’s openly accessible GitHub repository.
- the README.md has information on options configuration, installation, uninstallation, platforms and more
- the help files for the functions can be accessed from R with
?languageserver_install
,?languageserver_startup
,?languageserver_add_to_rprofile
and?languageserver_remove_from_rprofile
for more details on their arguments and customization - for testing, GitHub actions are set up for multiple platforms and to run all CRAN checks on the package on each commit
References
- The R extension for VS Code Marketplace
- The R LSP Client extension on VS Code Marketplace
- The languageserver package on GitHub
- The languageserversetup package on GitHub
- Kun Ren’s Writing R in VSCode: A Fresh Start blogpost