Skip to content

Instantly share code, notes, and snippets.

@pansapiens
Last active April 29, 2024 06:02
Show Gist options
  • Save pansapiens/088f599be11c6f3c63a91c051a7b2fea to your computer and use it in GitHub Desktop.
Save pansapiens/088f599be11c6f3c63a91c051a7b2fea to your computer and use it in GitHub Desktop.
tmux persistent R session for vscode-R

Persistent R in tmux for vscode-R

This is a set of wrapper scripts and a configuration guide to allow you to have a persistent R session on a server when using the Visual Studio Code R Extension.

Current caveats:

  • Only one R session
    • (workaround: use vscode workspace settings, and keep a copy of R-vscode-remote.sh in the project workspace, configured with a particular R_BINARY and unique R_TMUX_SESSION_NAME)
  • R version chosen via an environment variable (R_BINARY)
  • No radian (seem to have issues)

Setup

Install wrapper scripts

Copy R-vscode-remote.sh and R-kill-vscode-remote.sh to your remote machine (I put them in ~/bin, on PATH). Ensure they are executable (chmod +x R-vscode-remote.sh R-kill-vscode-remote.sh).

mkdir -p ~/bin

wget -O ~/bin/R-vscode-remote.sh https://gist.githubusercontent.com/pansapiens/088f599be11c6f3c63a91c051a7b2fea/raw/e7e33bb657770863b81f73b76c7e0db3190ad657/R-vscode-remote.sh

wget -O ~/bin/R-kill-vscode-remote.sh https://gist.githubusercontent.com/pansapiens/088f599be11c6f3c63a91c051a7b2fea/raw/e7e33bb657770863b81f73b76c7e0db3190ad657/R-kill-vscode-remote.sh

chmod +X R-vscode-remote.sh R-kill-vscode-remote.sh

# You may wish to add this to ~/.bashrc
#export PATH=$PATH:$HOME/bin

To choose an R version, edit R_BINARY near the top of R-vscode-remote.sh (or set the R_BINARY in your ~/.bashrc).

Install supporting R packages

Install some support packages in R (eg in your renv):

renv::install(c("languageserver", "httpgd", "ManuelHentschel/vscDebugger"))

Or if using a conda environment with associated R packages:

conda install -y r-httpuv r-languageserver

# compiles with conda's own gcc compiler
Rscript -e 'install.packages("vscDebugger", repos = "https://manuelhentschel.r-universe.dev")'

# or if you trust a random 3rd-party R package ...
# conda install -y tttpob::r-vscdebugger

Edit .RProfile

To your .RProfile, add:

#  ~/.RProfile, or a project specific renv .RProfile

# Add this below any renv and workflowr initialization code

Sys.setenv(TERM_PROGRAM="vscode")
if (interactive() && Sys.getenv("RSTUDIO") == "") {
  source(file.path(Sys.getenv(if (.Platform$OS.type == "windows") "USERPROFILE" else "HOME"), ".vscode-R", "init.R"))
}

# options(vsc.rstudioapi = TRUE)
options(vsc.viewer = "Beside")

If you are using renv, this needs to be done per-project for each renv where you want to use this wrapper.

Configure the vscode-R Extension

Install the vscode-R extension and R Debugger Extension if you don't have them.

Configure the vscode R extension:

  • R > Rterm: Linux (r.rterm.linux): ~/bin/R-vscode-remote.sh <- path to your copy of R-vscode-remote.sh

Some of these may be optional:

  • R > Plot > Use Httpgd (r.plot.useHttpgd): true
  • R > Plot > Defaults: Full Window Mode (r.plot.defaults.fullWindowMode): true
  • R > Plot > Timing: Refresh Interval (r.plot.timing.refreshInterval): 50 (ms) - adjust higher if plots have issues updating
  • R > Lsp Enabled (r.lsp.enabled): true
  • R > Lsp: Use_stdio (r.lsp.use_stdio): true
  • R > Remove Leading Comments (r.removeLeadingComments): true
  • R > Rterm Send Delay (r.rtermSendDelay): 15 (ms)
  • R > Session: Use Web Server (r.session.useWebServer): true
  • R > Use Renv Lib Path (r.useRenvLibPath): true (assuming you are using renv)

You may wish to refer to the vscode-R docs for further detail.

Usage

Open an RMarkdown document, or open an R Terminal. Run some R code in the R Terminal, or click "Run Chunk" in the R Markdown to send a chunk of code to the R Terminal.

Click on the R logo in the left sidebar (or right click there to enable it) to see the R Environment 'variable browser'.

(TODO: Screenshots here)

Once the R tmux session is running (named vscode-r by default), R auto-restarts every time you quit it. To kill the session, run: R-kill-vscode-remote.sh

Troubleshooting

Problem: My plots aren't appearing, or I don't see any variables in the left hand side R pane.

Solution: Check that the extension has attached to the R interpretor (see bottom right corner of vscode, "R 4.3.1: xxxxx" - click there if it doesn't or type: .vsc.attach() in the R Terminal).

#!/bin/bash
R_TMUX_SESSION_NAME="${R_TMUX_SESSION_NAME:-vscode-r}"
TMUX_CMD=$(command -v tmux)
if ! [ -x "$(command -v tmux)" ]; then
echo "Error: tmux is not installed."
exit 1
fi
$TMUX_CMD kill-session -t $R_TMUX_SESSION_NAME
#!/bin/bash
# You should set the vscode settings variable: r.rterm.linux to the path of this script.
#
# For further config and debugging, see:
# https://github.com/REditorSupport/vscode-R/wiki/R-Session-watcher#advanced-usage-for-self-managed-r-sessions
# Your renv should contain:
# renv::install(c("languageserver", "httpuv", "ManuelHentschel/vscDebugger", "nx10/httpgd"))
# You may need to add this to your ~/.Rprofile (or in the project, after the renv line) to allow the R extension to attach with .vsc.attach():
#
# if (interactive() && Sys.getenv("RSTUDIO") == "") {
# source(file.path(Sys.getenv(if (.Platform$OS.type == "windows") "USERPROFILE" else "HOME"), ".vscode-R", "init.R"))
# }
# options(vsc.rstudioapi = TRUE)
# options(vsc.viewer = "Beside")
###########################
# Required to get vscode to attach to the R session
# export TERM_PROGRAM=vscode
# Default R_BINARY if not set
export R_BINARY=${R_BINARY:-$(command -v R)}
#export R_BINARY=/mnt/software/apps/R/4.3.1/bin/R
_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
MY_PATH="${_dir}/$(basename "$0")"
R_TMUX_SESSION_NAME="${R_TMUX_SESSION_NAME:-vscode-r}"
TMUX_CMD=$(command -v tmux)
if ! [ -x "$(command -v "$R_BINARY")" ]; then
echo "Error: $R_BINARY is not executable."
exit 1
fi
if ! [ -x "$(command -v tmux)" ]; then
echo "Error: tmux is not installed."
exit 1
fi
R_REPL=${R_BINARY}
#if [ -x "$(command -v radian)" ]; then
# R_REPL="$(command -v radian) --r-binary ${R_BINARY}"
#fi
# Store all command-line arguments in a variable
R_ARGS="$@"
# Check if session already exists
$TMUX_CMD has-session -t $R_TMUX_SESSION_NAME 2>/dev/null
# $? is a shell variable that represents the exit code of the last run command
if [ $? != 0 ]; then
# Start new session with the specified name, passing any command-line arguments to R
$TMUX_CMD new-session -d -s $R_TMUX_SESSION_NAME "\
while [[ true ]]; do \
echo To use this script as intended, the vscode setting for r.rterm.linux should be set to: ${MY_PATH}; \
echo To kill this tmux session, outside tmux run: ${TMUX_CMD} kill-session -t ${R_TMUX_SESSION_NAME}; echo; echo; \
TERM_PROGRAM=vscode ${R_REPL} ${R_ARGS}; \
done"
fi
# Attach to the session
$TMUX_CMD attach -t $R_TMUX_SESSION_NAME
# To kill a running session, do:
# tmux kill-session -t $R_TMUX_SESSION_NAME
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment