diff --git a/src/commands/text.ts b/src/commands/text.ts index 2ef811c..23ce5b2 100755 --- a/src/commands/text.ts +++ b/src/commands/text.ts @@ -1,8 +1,10 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.textCommands = void 0; + const vscode = require("vscode"); const pl = require("../pylex"); + exports.textCommands = [ { name: 'mind-reader.getLineNumber', @@ -25,6 +27,7 @@ exports.textCommands = [ callback: runCursorContext } ]; + /* Helper Function * This function returns the line number of the active text editor window */ @@ -32,6 +35,13 @@ function fetchLineNumber(editor) { return editor.selection.active.line + 1; } +/* Helper Function + * This function returns the text from the current line of the active text editor window + */ +function fetchTextLine(editor) { + return editor.document.lineAt(fetchLineNumber(editor) - 1); +} + // Function that outputs the current line number the cursor is on function getLineNumber() { let editor = vscode.window.activeTextEditor; @@ -47,9 +57,11 @@ function getLineNumber() { function getIndent() { let editor = vscode.window.activeTextEditor; + if (editor) { let lineNum = fetchLineNumber(editor); - let textLine = editor.document.lineAt(lineNum - 1); + let textLine = fetchTextLine(editor); + if (textLine.isEmptyOrWhitespace) { vscode.window.showInformationMessage(`"Line ${lineNum.toString()} is Empty`); } @@ -60,38 +72,70 @@ function getIndent() { hard: !editor.options.insertSpaces }; let i = pl.Lexer.getIndent(textLine.text, tabFmt); - vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indents`); + + // Ternary operator to change the tense of 'indent' to 'indents' for the output if i is greater than 1 + (i > 1) ? + vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indents`) : + vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indent`); } } else { vscode.window.showErrorMessage('No document currently active'); } } + /* Function -> Returns the number of leading spaces on the line the cursor is on - * This is done by returning the index of the first non whitespace character - * Since this index is a 0-index, the returned number will correspond to the number of leading spaces + * There are two methods that can be used to find the leading spaces: + * method 1: + * calculates the number of leading spaces by finding the length of the current line + * then subtracting from that the length of the text after trimming the whitespace at the start + * which will equal the number of whitespace characters + * + * TO-USE: set calculateLeadingSpaces to true + * + * method 2 (default): + * finds the index position of the first non-whitespace character in a 0-index + * this number will equal the number of spaces preceding the non-whitespace character + * due to the nature of 0-indexes. + * + * TO-USE: set calculateLeadingSpaces to false */ function getLeadingSpaces() { let editor = vscode.window.activeTextEditor; if (editor) { - let lineNum = fetchLineNumber(editor); - let textLine = editor.document.lineAt(lineNum - 1); - if(textLine.isEmptyOrWhitespace) { + const lineNum = fetchLineNumber(editor); + const textLine = fetchTextLine(editor); + + if (textLine.isEmptyOrWhitespace) { vscode.window.showInformationMessage(`Line ${lineNum.toString()} is empty`); } else { - let numSpaces = textLine.firstNonWhitespaceCharacterIndex; - // let numSpaces = textLine.text.length - textLine.text.trimStart().length; // Alternative method, same result by calculating the leading spaces - vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} spaces`); + /* + * set true to use method 1: find the number of leading spaces through arithmetic + * set false to use method 2: find the index position of the first non-whitespace character in a 0-index + * + * default: false + */ + const calculateLeadingSpaces = false; // change boolean value to change method + const numSpaces = (calculateLeadingSpaces === true) ? + pl.Lexer.getLeadingSpacesByArithmetic(textLine) : + pl.Lexer.getLeadingSpacesByIndex(textLine); + + /* Ternary operator to change the tense of 'space' to 'spaces' for the output if numSpaces is greater than 1 */ + (numSpaces > 1) ? + vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} spaces`) : + vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} space`); } } else { vscode.window.showErrorMessage('No document currently active'); } } + function runLineContext() { let editor = vscode.window.activeTextEditor; + if (editor) { // current text and line number let editorText = editor.document.getText(); @@ -105,27 +149,34 @@ function runLineContext() { let context = parser.context(line); // build text let contentString = createContextString(context, line); + vscode.window.showInformationMessage(contentString); } else { vscode.window.showErrorMessage('No document currently active'); } } + function createContextString(context, line) { if (context.length < 1) { throw new Error('Cannot create context string for empty context'); } + let contextString = 'Line ' + (line + 1); // 1 based + if (context[0].token && context[0].token.attr) { contextString += ': ' + context[0].token.type.toString() + ' ' + context[0].token.attr.toString(); } + for (let i = 1; i < context.length; i++) { let node = context[i]; + if (node.label === 'root') { // root contextString += ' in the Document Root'; continue; } + if (node.token.type !== pl.PylexSymbol.EMPTY && node.token.type !== pl.PylexSymbol.INDENT) { contextString += ' inside ' + node.token.type.toString(); @@ -136,14 +187,17 @@ function createContextString(context, line) { } return contextString; } + // find up to `n` words around the cursor, where `n` is // the value of `#mindReader.reader.contextWindow` function runCursorContext() { let editor = vscode.window.activeTextEditor; + if (!editor) { vscode.window.showErrorMessage('RunCursorContext: No Active Editor'); return; } + const cursorPos = editor.selection.active; const text = editor.document.lineAt(cursorPos).text; const windowSize = vscode.workspace.getConfiguration('mindReader').get('reader.contextWindow'); @@ -154,6 +208,7 @@ function runCursorContext() { let maxPos = text.length; // clamp cursor start/end to new range let col = cursorPos.character; // effective column of the cursor position + if (col < leadingWS) { // move effective start to first non-whitespace character in the line col = leadingWS; @@ -162,11 +217,14 @@ function runCursorContext() { // move effective end to last non-whitespace character in the line col = leadingWS + trimmedText.length - 1; } + // generate list of space separate words with range data (start, end) // TODO: can find user position to be done in one pass let spaceWords = []; + while (pos < maxPos && trimmedText.length > 0) { let word = trimmedText.replace(/ .*/, ''); + spaceWords.push({ word, start: pos, end: pos + word.length }); // remove processed word from trimmed text const oldText = trimmedText; @@ -176,6 +234,7 @@ function runCursorContext() { } // find word the user is in let contextStart = -1, contextEnd = -1; + for (let i = 0; i < spaceWords.length; i++) { if (col >= spaceWords[i].start && col <= spaceWords[i].end) { // found the word @@ -183,6 +242,7 @@ function runCursorContext() { contextEnd = Math.min(spaceWords.length, i + windowSize + 1); // clamp end index // construct cursor context string let contextString = ''; + for (let i = contextStart; i < contextEnd; i++) { contextString += spaceWords[i].word + ' '; }