Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
416922d
initial commit of proc_r embedded lang test
Wizzzzzzard Dec 4, 2025
74a5d31
adding R language options to client and notebook
Wizzzzzzard Dec 5, 2025
0231587
adding some R Code test fixtures
Wizzzzzzard Dec 5, 2025
8f22394
fixing rlang testfixture file name
Wizzzzzzard Dec 5, 2025
97489e5
adding a print statement to debug rlang zonelist
Wizzzzzzard Dec 5, 2025
696bddd
updating debug function for zone_type assertions
Wizzzzzzard Dec 5, 2025
a05b28f
DCO Remediation Commit for Elijah Cúchulainn Reid <56865341+Wizzzzzza…
Wizzzzzzard Dec 5, 2025
29dfd9a
Updating Lexer to correctly parse PROC RLANG code
Wizzzzzzard Dec 5, 2025
0e2b746
Adding PROC_RLANG to CodeZoneManager
Wizzzzzzard Dec 5, 2025
398c156
Adding R as an option to the parser for formatting
Wizzzzzzard Dec 5, 2025
ca52898
DCO Remediation Commit for Elijah Cúchulainn Reid <56865341+Wizzzzzza…
Wizzzzzzard Dec 5, 2025
454a6ab
test with simpler rlang script
Wizzzzzzard Dec 5, 2025
5e4da15
resetting to more complex Rlang file
Wizzzzzzard Dec 5, 2025
a3be20b
fixing file
Wizzzzzzard Dec 5, 2025
412995f
adding more rlang tests to match pre-existing lua and python ones
Wizzzzzzard Dec 5, 2025
e62c8e8
reverting embedded lang test assert for rlang
Wizzzzzzard Dec 5, 2025
c5f8f7f
updating references to "rlang" as a language to "r" to work better wi…
Wizzzzzzard Dec 5, 2025
d4da7ad
making spacing a bit nicer
Wizzzzzzard Dec 5, 2025
7e58b1c
tweaking R UID to see if it makes a difference
Wizzzzzzard Dec 5, 2025
925ff77
Updating notebook with correctly highlighted R code
Wizzzzzzard Dec 5, 2025
9e1b66a
uploading notebook with R output
Wizzzzzzard Dec 5, 2025
3b41802
making the rlang id match python
Wizzzzzzard Dec 5, 2025
54f72e3
Updating references to languages in docs to include R
Wizzzzzzard Dec 5, 2025
82d5f26
Including R changes in the Changelog
Wizzzzzzard Dec 5, 2025
ca092d2
removing rlang case now that references have been updated to r
Wizzzzzzard Dec 5, 2025
adc239c
removing debug function from CodeZoneManager
Wizzzzzzard Dec 5, 2025
18cba79
Simplifying R comment/string regex in Lexer
Wizzzzzzard Dec 5, 2025
7901b2b
turning on git always sign off in vscode settings to help with DCO Is…
Wizzzzzzard Dec 5, 2025
3eab50d
Add R code extraction utilities and type definitions
Wizzzzzzard Dec 8, 2025
62e89e8
Add R IntelliSense for PROC RLANG blocks
Wizzzzzzard Dec 8, 2025
759b1d4
Wire R language providers into SAS LSP server
Wizzzzzzard Dec 8, 2025
43ce626
Add PROC RLANG test fixture
Wizzzzzzard Dec 8, 2025
18fbd54
Document R language support features
Wizzzzzzard Dec 8, 2025
ed369f4
Spacing fixes
Wizzzzzzard Dec 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"git.alwaysSignOff": true,
"typescript.tsc.autoDetect": "off",
"typescript.preferences.quoteStyle": "single"
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Add the ability to sort columns in data viewer and view column properties ([#1622](https://github.com/sassoftware/vscode-sas-extension/pull/1622))
- Add code comment collapsing ([#1638](https://github.com/sassoftware/vscode-sas-extension/pull/1638))
- Add ability to view dataset properties ([#1631](https://github.com/sassoftware/vscode-sas-extension/pull/1631))
- Add R language support for PROC RLANG (syntax highlighting, notebook cells, code formatting preservation)

### Fixed

Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,20 @@ The SAS extension includes many [features](https://sassoftware.github.io/vscode-

- SAS syntax highlighting and help, code completion, and code snippets
- Navigate SAS Content and libraries, including table viewer
- Create notebooks for SAS, SQL, Python and other languages
- Create notebooks for SAS, SQL, Python, R, and other languages

<img src="website/static/images/featuresGlance.png"/>

## Language Support

The SAS extension provides enhanced language support for embedded languages in SAS notebooks and code files:

- **Python**: Full IntelliSense support (code completion, hover, signature help) is included via Pyright
- **R**:
- **In VS Code Desktop**: Basic IntelliSense support (code completion, hover) for common R functions - no installation required
- **In Browser (VS Code for Web)**: Basic IntelliSense support provided automatically via WebR (no installation required)
- **SQL** and **Lua**: Syntax highlighting and execution support

## Support

### SAS Communities
Expand Down
3 changes: 3 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion client/src/components/ContentNavigator/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ const stepRef: Record<string, string> = {
sas: "a7190700-f59c-4a94-afe2-214ce639fcde",
sql: "a7190700-f59c-4a94-afe2-214ce639fcde",
python: "ab59f8c4-af9a-4608-a5d5-a8365357bb99",
rlang: "ab59f8c4-af9a-4608-a5d5-a8365357bb99",
};

const stepTitle: Record<string, string> = {
sas: l10n.t("SAS Program"),
sql: l10n.t("SQL Program"),
python: l10n.t("Python Program"),
rlang: l10n.t("R Program"),
};

const NODE_SPACING = 150;
Expand Down Expand Up @@ -305,7 +307,7 @@ function generateCodeListFromSASNotebook(content: string): Entry[] {
let code = cell.value;
if (code !== "") {
const language = cell.language;
if (["python", "sas", "sql"].includes(language)) {
if (["python", "sas", "sql", "rlang"].includes(language)) {
if (language === "sql") {
code = `PROC SQL;
${code};
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/notebook/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class NotebookController {
readonly controllerId = "sas-notebook-controller-id";
readonly notebookType = "sas-notebook";
readonly label = "SAS Notebook";
readonly supportedLanguages = ["sas", "sql", "python"];
readonly supportedLanguages = ["sas", "sql", "python", "r"];

private readonly _controller: vscode.NotebookController;
private _executionOrder = 0;
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/notebook/exporters/toHTML.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { readFileSync } from "fs";
import hljs from "highlight.js/lib/core";
import python from "highlight.js/lib/languages/python";
import r from "highlight.js/lib/languages/r";
import sql from "highlight.js/lib/languages/sql";
import { marked } from "marked";
import path from "path";
Expand All @@ -27,6 +28,7 @@ import { includeLogInNotebookExport } from "../../utils/settings";
const templatesDir = path.resolve(__dirname, "../notebook/exporters/templates");

hljs.registerLanguage("python", python);
hljs.registerLanguage("r", r);
hljs.registerLanguage("sql", sql);

export const exportToHTML = async (
Expand Down
8 changes: 8 additions & 0 deletions client/src/components/notebook/exporters/toSAS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const exportCell = (cell: NotebookCell) => {
return text;
case "python":
return wrapPython(text);
case "r":
return wrapRlang(text);
case "sql":
return wrapSQL(text);
case "markdown":
Expand All @@ -36,3 +38,9 @@ submit;
${code}
endsubmit;
run;`;

const wrapRlang = (code: string) => `proc rlang;
submit;
${code}
endsubmit;
run;`;
15 changes: 15 additions & 0 deletions client/src/components/utils/SASCodeDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ endsubmit;
run;`;
}

private wrapRlang(code: string) {
return `proc rlang;
submit;
${code}
endsubmit;
run;`;
}

private insertLogStartIndicator(code: string): string {
// add a comment line at the top of code,
// this comment line will be used as indicator to the beginning of log related with this code
Expand All @@ -198,6 +206,13 @@ ${code}`;
wrapped = this.wrapPython(wrapped);
}

if (
this.parameters.languageId === "r" ||
this.parameters.languageId === "rlang"
) {
wrapped = this.wrapRlang(wrapped);
}

wrapped = this.wrapCodeWithSASProgramFileName(wrapped);

wrapped = this.wrapCodeWithPreambleAndPostamble(wrapped);
Expand Down
34 changes: 34 additions & 0 deletions client/test/components/util/SASCodeDocument.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,40 @@ run;
assert.equal(sasCodeDoc.getWrappedCode(), expected);
});

it("wrap rlang code", () => {
const parameters: SASCodeDocumentParameters = {
languageId: "r",
code: `for (x in 1:6) {
print(x)
}
print("test")`,
selectedCode: "",
htmlStyle: "Illuminate",
outputHtml: true,
uuid: "519058ad-d33b-4b5c-9d23-4cc8d6ffb163",
checkKeyword: async () => false,
};

const sasCodeDoc = new SASCodeDocument(parameters);

const expected = `/** LOG_START_INDICATOR **/
title;footnote;ods _all_ close;
ods graphics on;
ods html5(id=vscode) style=Illuminate options(bitmap_mode='inline' svg_mode='inline') body="519058ad-d33b-4b5c-9d23-4cc8d6ffb163.htm";
proc rlang;
submit;
for (x in 1:6) {
print(x)
}
print("test")
endsubmit;
run;
;*';*";*/;run;quit;ods html5(id=vscode) close;
`;

assert.equal(sasCodeDoc.getWrappedCode(), expected);
});

it("wrap sql code", () => {
const parameters: SASCodeDocumentParameters = {
languageId: "sql",
Expand Down
21 changes: 21 additions & 0 deletions client/testFixture/formatter/expected.sas
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ def my_function():
endsubmit;
run;

proc rlang;
submit;
# Reference to variable defined in previous PROC RLANG call
print(paste("x =", x))
my_function <- function() {
print("Inside the proc step")
}
endsubmit;
run;

proc lua;
submit;
local dsid = sas.open("sashelp.company") -- open for input
Expand Down Expand Up @@ -131,6 +141,17 @@ print('first statement after for loop')
endinteractive;
run;

proc rlang;
submit;
fruits <- c("apple", "banana", "cherry")
for (x in fruits) {
print(x)
}

print('first statement after for loop')
endsubmit;
run;

proc lua;
submit;

Expand Down
20 changes: 20 additions & 0 deletions client/testFixture/formatter/unformatted.sas
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ def my_function():
print("Inside the proc step")
endsubmit;
run;
proc rlang;
submit;
# Reference to variable defined in previous PROC RLANG call
print(paste("x =", x))
my_function <- function() {
print("Inside the proc step")
}
endsubmit;
run;
proc lua;
submit;
local dsid = sas.open("sashelp.company") -- open for input
Expand Down Expand Up @@ -126,6 +135,17 @@ print('first statement after for loop')
endinteractive;
run;

proc rlang;
submit;
fruits <- c("apple", "banana", "cherry")
for (x in fruits) {
print(x)
}

print('first statement after for loop')
endsubmit;
run;

proc lua;
submit;

Expand Down
17 changes: 17 additions & 0 deletions client/testFixture/sasnb_export.sas
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ print("Result: ", a*10 + b)
endsubmit;
run;

/*
## R Code
This is some R code
*/

/*
This is a separate note in **Markdown** format.
*/

proc rlang;
submit;
die <- 1:6
paste("Die Maths: ", die[3]*4 + die[6])
endsubmit;
run;

/*
## SAS Code
*/
Expand Down
2 changes: 1 addition & 1 deletion client/testFixture/sasnb_export.sasnb

Large diffs are not rendered by default.

Loading
Loading