Skip to content

Installation

Set up Roughly in VS Code, Zed, RStudio, or on the command line

Roughly runs as an editor extension (the comfortable way) or as a standalone CLI (for scripts and CI). Pick whichever fits; they are the same binary underneath.

Install the Roughly extension from the VS Code Marketplace. The extension bundles the Roughly CLI for Linux x86_64, macOS aarch64, and Windows x86_64, so there is nothing else to set up.

On another architecture, install the CLI separately and point the extension at it with the roughly.path setting (see the language server page).

Install the R extension (Zed has no built-in R support), then the Roughly extension from Zed’s extension registry.

To also get Roughly’s #: annotation highlighting in Zed, enable LSP semantic tokens for R — see the language server page.

Use the CLI directly for formatting and linting in CI, with RStudio, or to back an editor extension on a platform without a bundled binary. Install it in whichever way suits you — a prebuilt binary, or from source with Cargo.

Prebuilt binary (Linux, macOS, and Windows):

  1. Download the binary for your platform from the GitHub Releases page.
  2. Add it to your system PATH.

With Cargo, if you have a Rust toolchain:

Terminal window
cargo install --git https://github.com/felix-andreas/roughly roughly

You can configure Roughly as an external formatter in RStudio:

  1. Open RStudio and navigate to:

    Options > Code > Formatting > Format with an External Tool

    Set the reformat command to: path/to/roughly fmt

  2. To enable format-on-save, go to:

    Options > Code > Saving > Format with an External Tool

    Check the Reformat documents on save option.

The CLI has three commands:

Terminal window
# Format R files (rewrites in place)
roughly fmt # format files in the current directory
roughly fmt path/to/files # format files at a specific path
roughly fmt --check # list files that would change, exit 1 (for CI)
roughly fmt --diff # show the diff without writing
# Lint and type-check
roughly check # check files in the current directory
roughly check path/to/files
roughly check --output json # one JSON object per diagnostic (for CI)
roughly check --min-severity error # only errors render and affect the exit code
# Run the language server (for editors that speak LSP)
roughly server

roughly check runs the linter by default. To also surface type errors and unused-variable warnings, opt in through roughly.toml:

[check]
typing = true # report type errors
unused = true # report unused local variables

Type inference itself is always on and powers editor features like hover and inlay hints — the settings above only control which diagnostics roughly check reports.

roughly check --output json writes one JSON object per diagnostic to stdout (JSON Lines); progress and error messages stay on stderr, so stdout is pure JSON:

{"path":"R/utils.R","line":2,"column":3,"endLine":2,"endColumn":7,"severity":"error","code":"syntax-error","message":"Syntax Error: unexpected \"<- (\""}

line/column/endLine/endColumn are 1-based, severity is "error" or "warning", and code is the diagnostic’s stable code. related lists the locations a diagnostic points at beyond its own range — for example, each “overwrites an earlier top-level binding” warning names the sibling binding site — as {path, line, column, endLine, endColumn, message} objects (empty when a diagnostic stands alone). These field names are a contract — safe to build CI on.

roughly check and roughly fmt share one scheme:

CodeMeaning
0Clean — no diagnostics (check); nothing to change (fmt)
1Findings — any diagnostic, warnings included (check); files that would be reformatted (fmt --check, fmt --diff)
2Usage, configuration, or I/O error

A warnings-only check run exits 1 by default; pass --min-severity error to gate on errors only.