diff --git a/package.json b/package.json index 1c709d62f..6c077b6c9 100644 --- a/package.json +++ b/package.json @@ -1558,7 +1558,12 @@ "r.bracketedPaste": { "type": "boolean", "default": false, - "description": "Use bracketed paste mode when sending code to console. Enable for Radian console." + "markdownDescription": "Use bracketed paste mode when sending code to terminal. Enable for [radian](https://github.com/randy3k/radian) console." + }, + "r.removeLeadingComments": { + "type": "boolean", + "default": false, + "description": "Remove leading comments when sending code to terminal." }, "r.sessionWatcher": { "type": "boolean", diff --git a/src/selection.ts b/src/selection.ts index 3e50c55df..b3bce7f3d 100644 --- a/src/selection.ts +++ b/src/selection.ts @@ -3,6 +3,7 @@ import { Position, Range, window } from 'vscode'; import { LineCache } from './lineCache'; +import { config } from './util'; export function getWordOrSelection(): string | undefined { const textEditor = window.activeTextEditor; @@ -72,7 +73,13 @@ export function getSelection(): RSelection | undefined { selection.range = new Range(newStart, newEnd); } - selection.selectedText = currentDocument.getText(selection.range).trim(); + let selectedText = currentDocument.getText(selection.range).trim(); + + if (config().get('removeLeadingComments')) { + selectedText = removeLeadingComments(selectedText); + } + + selection.selectedText = selectedText; return selection; } @@ -278,3 +285,23 @@ export function extendSelection(line: number, getLine: (line: number) => string, return ({ startLine: poss[0].line, endLine: poss[1].line }); } + + +/** + * This function removes leading R comments from a block of code text + * I.e. All blank and commented out lines are removed up until we hit the first + * non-blank / non-comment line. + * @param text A block of R code as a string + */ +export function removeLeadingComments(text: string): string { + const textArray = text.split('\n'); + let endSearchIndex = 0; + for (const lineContent of textArray) { + if (lineContent.search('(^ *$|^ *#)') !== -1) { + endSearchIndex += 1; + } else { + break; + } + } + return textArray.slice(endSearchIndex).join('\n'); +} diff --git a/src/test/suite/removeLeadingComments.test.ts b/src/test/suite/removeLeadingComments.test.ts new file mode 100644 index 000000000..dea933ed7 --- /dev/null +++ b/src/test/suite/removeLeadingComments.test.ts @@ -0,0 +1,67 @@ + + +import * as assert from 'assert'; +import { removeLeadingComments } from '../../selection'; + +// Defines a Mocha test suite to group tests of similar kind together +suite('removeLeadingComments Tests', () => { + + + test('Check that nothing changes if no comments', () => { + const input = `\ + function (x) { + y = x + y + } + `; + const expectedOutput = `\ + function (x) { + y = x + y + } + `; + const result = removeLeadingComments(input); + assert.strictEqual(result, expectedOutput); + }); + + test('Check that basic comments are removed', () => { + const input = `\ + # a leading comment + function (x) { + y = x + y + } + `; + const expectedOutput = `\ + function (x) { + y = x + y + } + `; + const result = removeLeadingComments(input); + assert.strictEqual(result, expectedOutput); + }); + + test('Check that inner comments are not removed', () => { + const input = `\ + + # a leading comment + # Another leading comment + + function (x) { + y = x + # inner comment + y + } + `; + const expectedOutput = `\ + function (x) { + y = x + # inner comment + y + } + `; + const result = removeLeadingComments(input); + assert.strictEqual(result, expectedOutput); + }); +});