Skip to content

Commit

Permalink
Merge pull request #184 from renkun-ken/update-readme
Browse files Browse the repository at this point in the history
Improve session watcher initialization
  • Loading branch information
andycraig authored Jan 24, 2020
2 parents b6597b5 + 75a5edd commit 625ae35
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 16 deletions.
11 changes: 11 additions & 0 deletions R/.Rprofile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
if (nzchar(Sys.getenv("R_PROFILE_USER_OLD"))) {
source(Sys.getenv("R_PROFILE_USER_OLD"))
} else if (file.exists(".Rprofile")) {
source(".Rprofile")
} else if (file.exists("~/.Rprofile")) {
source("~/.Rprofile")
}

if (is.null(getOption("vscodeR"))) {
source(file.path(Sys.getenv(if (.Platform$OS.type == "windows") "USERPROFILE" else "HOME"), ".vscode-R", "init.R"))
}
2 changes: 1 addition & 1 deletion R/init.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if (interactive() && !identical(Sys.getenv("RSTUDIO"), "1")) {
if (interactive() && Sys.getenv("TERM_PROGRAM") == "vscode") {
if (requireNamespace("jsonlite", quietly = TRUE)) {
local({
pid <- Sys.getpid()
Expand Down
59 changes: 49 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,53 @@ This extension contributes the following settings:
An opt-in experimental R session watcher is implemented to support the following features:

* Watch any R session
* Show value of session symbol on hover
* Provide completion for session symbol
* `View()` data frames and list objects
* Show plot output on update
* Show htmlwidgets and shiny apps
* Show value of session symbols on hover
* Provide completion for session symbols
* `View()` any objects including data frames and list objects
* Show plot output on update and plot history
* Show htmlwidgets, documentation and shiny apps in WebView

To enable this feature, turn on `r.sessionWatcher` and append the following code to your `.Rprofile` (in your home directory):
### Basic usage

```r
source(file.path(if (.Platform$OS.type == "windows") file.path(Sys.getenv("HOMEDRIVE"), Sys.getenv("HOMEPATH")) else Sys.getenv("HOME"), ".vscode-R", "init.R"))
```
To enable this feature, turn on `r.sessionWatcher` in VSCode settings, reload or restart VSCode, and the session watcher will be activated automatically
on R sessions launched by vscode-R via `R: Create R Terminal` command.

*If you previously appended the `source(...)` line to `~/.Rprofile`, you may safely remove it since the configuration for basic usage is automated. It is
now only necessary for advanced usage described below.*

### Advanced usage (for self-managed R sessions)

For advanced users to work with self-managed R sessions (e.g. manually launched R terminal or started in `tmux` or `screen` window), some extra
configuration is needed. Follow the steps below to make R session watcher work with any external R session:

1. Turn on `r.sessionWatcher` in VSCode settings.
2. Edit `.Rprofile` in your home directory by running the following code in R:

```r
file.edit("~/.Rprofile")
```

3. Append the following code to the file:

```r
source(file.path(Sys.getenv(if (.Platform$OS.type == "windows") "USERPROFILE" else "HOME"), ".vscode-R", "init.R"))
```

4. Restart or Reload Window in VSCode

If the workspace folder you open in VSCode already has a `.Rprofile`, you need to append the code above in this file too because `~/.Rprofile` will not
be executed when a local `.Rprofile` is found.

The script only works with environment variable `TERM_PROGRAM=vscode`. the script will not take effect with R sessions started in a `tmux` or `screen` window that does not have it, unless this environment variable is manually set before sourcing `init.R`, for example, you may insert a line `Sys.setenv(TERM_PROGRAM="vscode")` before it.

### How to disable it

For the case of basic usage, turning off `r.sessionWatcher` in VSCode settings is sufficient
to disable R session watcher.

For the case of advanced usage, user should, in addition, comment out or remove the `source(...)` line appended to `~/.Rprofile`.

### How it works

This script writes the metadata of symbols in the global environment and plot file to `${workspaceFolder}/.vscode/vscode-R/PID` where `PID` is the R process ID. It also captures user input and append command lines to `${workspaceFolder}/.vscode/vscode-R/response.log`, which enables the communication between vscode-R and a live R sesson.

Expand All @@ -91,7 +127,7 @@ R sessions started from the workspace root folder will be automatically attached
* R session started by vscode-R or user
* R session in a `tmux` or `screen` window
* Switch between multiple running R sessions
* [Remote Development](https://code.visualstudio.com/docs/remote/remote-overview)
* [Remote Development](https://code.visualstudio.com/docs/remote/remote-overview) via SSH, WSL and Docker

The status bar item shows the process id of the attached R session. Click the status bar item and it will
attach to currently active session.
Expand All @@ -100,6 +136,9 @@ attach to currently active session.

![R session watcher](https://user-images.githubusercontent.com/4662568/70815935-65391480-1e09-11ea-9ad6-7ebbebf9a9c8.gif)

*The R terminal used in the screenshot is [radian](https://github.com/randy3k/radian) which is cross-platform and
supports syntax highlighting, auto-completion and many other features.*

## TODO

* Debug
Expand Down
18 changes: 16 additions & 2 deletions src/rTerminal.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
"use strict";

import os = require("os");
import path = require("path");

import { pathExists } from "fs-extra";
import { isDeepStrictEqual } from "util";
import { commands, Terminal, window } from "vscode";
import { commands, Terminal, window, TerminalOptions } from "vscode";

import { getSelection } from "./selection";
import { removeSessionFiles } from "./session";
Expand All @@ -18,7 +21,18 @@ export function createRTerm(preserveshow?: boolean): boolean {
const termOpt: string[] = config.get("rterm.option");
pathExists(termPath, (err, exists) => {
if (exists) {
rTerm = window.createTerminal(termName, termPath, termOpt);
let termOptions: TerminalOptions = {
name: termName,
shellPath: termPath,
shellArgs: termOpt
};
if (config.get("sessionWatcher")) {
termOptions.env = {
R_PROFILE_USER_OLD: process.env.R_PROFILE_USER,
R_PROFILE_USER: path.join(os.homedir(), ".vscode-R", ".Rprofile")
};
}
rTerm = window.createTerminal(termOptions);
rTerm.show(preserveshow);
return true;
}
Expand Down
6 changes: 3 additions & 3 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ const sessionDir = path.join(".vscode", "vscode-R");

export function deploySessionWatcher(extensionPath: string) {
resDir = path.join(extensionPath, "dist", "resources");
const srcPath = path.join(extensionPath, "R", "init.R");
const targetDir = path.join(os.homedir(), ".vscode-R");
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir);
}
const targetPath = path.join(targetDir, "init.R");
fs.copySync(srcPath, targetPath);

fs.copySync(path.join(extensionPath, "R", "init.R"), path.join(targetDir, "init.R"));
fs.copySync(path.join(extensionPath, "R", ".Rprofile"), path.join(targetDir, ".Rprofile"));
}

export function startResponseWatcher(sessionStatusBarItem: StatusBarItem) {
Expand Down

0 comments on commit 625ae35

Please sign in to comment.