Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
79 changes: 63 additions & 16 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import { commands, ExtensionContext, languages, Range, window, workspace} from "vscode";
import { commands, ExtensionContext, languages, Position, Range, window, workspace} from "vscode";
import { createGitignore } from "./rGitignore";
import { installLintr, lintr } from "./rLint";
import { createRTerm, deleteTerminal, rTerm } from "./rTerminal";
Expand Down Expand Up @@ -32,37 +32,82 @@ export function activate(context: ExtensionContext) {
rPath = [rPath, "echo = TRUE"].join(", ");
}
if (!rTerm) {
createRTerm(true);
const success = createRTerm(true);
if(!success){ return; }
}
rTerm.sendText(`source(${rPath})`);
setFocus();
}

function getSelection(): string[] {
function countBlockStartsAndEnds(textArray: string[]) {
let blockStartsCount = 0;
let blockEndsCount = 0;
for (const text of textArray) {
blockStartsCount += text.replace(/[^{]/g, "").length;
blockEndsCount += text.replace(/[^}]/g, "").length;
}
return { numberBlockStarts: blockStartsCount, numberBlockEnds: blockEndsCount };
}

function getSelection(): any {
const selection = { linesDownToMoveCursor: 0, selectedTextArray: [] };
const { start, end } = window.activeTextEditor.selection;
const currentDocument = window.activeTextEditor.document;
const range = new Range(start, end);
const selectedLineText = !range.isEmpty
? currentDocument.getText(new Range(start, end))
: currentDocument.lineAt(start.line).text;

const selectedTextArray = selectedLineText.split("\n");
let selectedLine: string;
if (!range.isEmpty) {
const newStart = new Position(start.line, 0);
selectedLine = currentDocument.getText(new Range(newStart, end));
} else {
selectedLine = currentDocument.lineAt(start.line).text;
}

const selectedTextArray = selectedLine.split("\n");

return selectedTextArray;
const blocks = countBlockStartsAndEnds(selectedTextArray);
if (blocks.numberBlockStarts > blocks.numberBlockEnds) {
let lineIndex = 1;
while (blocks.numberBlockStarts !== blocks.numberBlockEnds) {
selectedLine = currentDocument.lineAt(end.line + lineIndex).text;
selectedTextArray.push(selectedLine);

const thisLineBlocks = countBlockStartsAndEnds([selectedLine]);
blocks.numberBlockStarts += thisLineBlocks.numberBlockStarts;
blocks.numberBlockEnds += thisLineBlocks.numberBlockEnds;
lineIndex++;
}
selection.linesDownToMoveCursor = lineIndex;
} else if (blocks.numberBlockStarts < blocks.numberBlockEnds) {
let lineIndex = 1;
while (blocks.numberBlockStarts !== blocks.numberBlockEnds) {
selectedLine = currentDocument.lineAt(start.line - lineIndex).text;
selectedTextArray.unshift(selectedLine);

const thisLineBlocks = countBlockStartsAndEnds([selectedLine]);
blocks.numberBlockStarts += thisLineBlocks.numberBlockStarts;
blocks.numberBlockEnds += thisLineBlocks.numberBlockEnds;
lineIndex++;
}
selection.linesDownToMoveCursor = 0;
}
selection.selectedTextArray = selectedTextArray;

return selection;
}

async function runSelection() {
const selectedLineText = getSelection();
const selection = getSelection();

if (!rTerm) {
createRTerm(true);
const success = createRTerm(true);
if(!success){ return; }
await delay (200); // Let RTerm warm up
}

for (const line of selectedLineText) {
commands.executeCommand("cursorMove", { to: "down" });
commands.executeCommand("cursorMove", { to: "down", value: selection.linesDownToMoveCursor });
for (const line of selection.selectedTextArray) {
if (checkForComment(line)) { continue; }
await delay(5); // Increase delay if RTerm can't handle speed.
await delay(8); // Increase delay if RTerm can't handle speed.
rTerm.sendText(line);
}
setFocus();
Expand Down Expand Up @@ -100,7 +145,8 @@ export function activate(context: ExtensionContext) {

async function previewEnvironment() {
if (!rTerm) {
createRTerm(true);
const success = createRTerm(true);
if(!success){ return; }
}
const tmpDir = makeTmpDir();
const pathToTmpCsv = tmpDir + "/environment.csv";
Expand All @@ -118,7 +164,8 @@ export function activate(context: ExtensionContext) {

async function previewDataframe() {
if (!rTerm) {
createRTerm(true);
const success = createRTerm(true);
if(!success){ return; }
}

const dataframeName = getSelection();
Expand Down
15 changes: 12 additions & 3 deletions src/rTerminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@

import { Terminal, window } from "vscode";
import { config, getRpath } from "./util";
import fs = require("fs-extra");
export let rTerm: Terminal;

export function createRTerm(preserveshow?: boolean) {
export function createRTerm(preserveshow?: boolean): boolean {
const termName = "R";
const termPath = getRpath();
if (!termPath) {
return;
}
const termOpt = config.get("rterm.option") as string[];
rTerm = window.createTerminal(termName, termPath, termOpt);
rTerm.show(preserveshow);
fs.pathExists(termPath, (err, exists) => {
if(exists){
rTerm = window.createTerminal(termName, termPath, termOpt);
rTerm.show(preserveshow);
return true;
} else {
window.showErrorMessage("Cannot find R client. Please check R path in preferences and reload.");
return false;
}
})
}

export function deleteTerminal(term: Terminal) {
Expand Down
11 changes: 10 additions & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function getRpath() {
} else if ( process.platform === "linux") {
return config.get("rterm.linux") as string;
}else {
window.showErrorMessage(process.platform + "can't use R");
window.showErrorMessage(process.platform + " can't use R");
return "";
}
}
Expand Down Expand Up @@ -43,3 +43,12 @@ export function checkForSpecialCharacters(text) {
export function checkIfFileExists(filePath) {
return fs.existsSync(filePath);
}

export function assertRTerminalCreation(rTerm): boolean {
if(!rTerm) {
window.showErrorMessage("Could not create R terminal.")
return false;
} else {
return true;
}
}