Merge remote-tracking branch 'origin/thomasLane' into merge-johnbreaux-thomaslane

This commit is contained in:
2022-05-05 19:49:29 -05:00
6 changed files with 820 additions and 177 deletions

View File

@@ -1,7 +1,6 @@
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as vscode from "vscode";
import { CommandEntry } from './commandEntry';
import { CommandEntry } from "./commandEntry";
export const navCommands: CommandEntry[] = [
{
@@ -78,19 +77,58 @@ export const navCommands: CommandEntry[] = [
// COMMAND CALLBACK IMPLEMENTATIONS
function openWebview(): void {
//vscode.commands.executeCommand('workbench.action.zoomOut');
const panel = vscode.window.createWebviewPanel(
'mindReader', // Identifies the type of the webview. Used internally
'Mind Reader', // Title of the panel displayed to the user
"mind-reader", // Identifies the type of the webview. Used internally
"Mind Reader", // Title of the panel displayed to the user
vscode.ViewColumn.One, // Editor column to show the new webview panel in.
{}
); // Webview options. More on these later.
panel.webview.html = getWebviewContent('media/html/main.html');
panel.webview.html = getWebviewContent();
}
function getWebviewContent(filepath: string) {
return fs.readFileSync(filepath, {encoding: 'utf-8'});
function getWebviewContent() {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mind Reader</title>
</head>
<body>
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT6a4XaqHkKcxJ6ZFms1RNrRurcOfl-diW90DAdpAx0Kv-rtrLJXovIhcUpayqFHATkrQ&usqp=CAU" width="600" />
<p></p>
<h1>Welcome to Mind_Reader!</h1>
<p>We are the Single Semester Snobs and this is our tool to Help Blind Students Program Lego Mindstorms Robots in Python.</p>
<ul>
<li>
This tool includes features such as a hotkey that says how many spaces in the text starts, an Accessibility Pane,
Audio Alerts, and an advanced settings window.
<br>
The tool has hotkeys for both PC and Mac commands.
</li>
<li>This system is intended for everyone, but primarily for students K-12 who are visually impaired. </li>
<li>
Our goal is to provide an enhanced experience for students who are visually impaired that is transparent to
sighted students.
<br>
This allows for everyone to use the same software solution, whether or not they are
vision impaired.
</li>
</ul>
<p>Use the following key binding to bring up a page for all key bindings for windows
<br>
Control and Shift and 8
</p>
<p>Use this key binding to do the same for mac computers:
<br>
Command and Shift and 9
</p>
<h2>This is the Lego Spike Prime!</h2z>
<p></p>
<img src="https://cdn.vox-cdn.com/thumbor/qoaa6N2ppl7oj97MR-aj43qPy0w=/0x0:1024x576/920x613/filters:focal(431x207:593x369):format(webp)/cdn.vox-cdn.com/uploads/chorus_image/image/63339099/lego_spike.0.png" width="300" />
<p></p>
<a href="https://www.lego.com/en-us/product/lego-education-spike-prime-set-45678">Get the robot!</a>
</body>
</html>`;
}

View File

@@ -1,9 +1,7 @@
"use strict";
import { CommandEntry } from './commandEntry';
import vscode = require("vscode");
import pl = require("../pylex");
type TextEditor = vscode.TextEditor | undefined;
import pl = require("../pylex");
import { CommandEntry } from './commandEntry';
import { Position, Selection, TextEditor, TextLine, window, workspace } from "vscode";
export const textCommands: CommandEntry[] = [
{
@@ -18,6 +16,14 @@ export const textCommands: CommandEntry[] = [
name: 'mind-reader.getLeadingSpaces',
callback: getLeadingSpaces,
},
{
name: 'mind-reader.selectLeadingWhitespace',
callback: selectLeadingWhitespace
},
{
name: 'mind-reader.getNumberOfSelectedLines',
callback: getNumberOfSelectedLines,
},
{
name: 'mind-reader.getLineScope',
callback: runLineContext,
@@ -28,43 +34,131 @@ export const textCommands: CommandEntry[] = [
}
];
/* Helper Function
* This function returns the line number of the active text editor window
/** Helper Function
*
* @param editor
* @returns numSpaces
** 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 fetchLineNumber(editor: TextEditor): number {
return editor? editor.selection.active.line + 1: -1;
}
function fetchNumberOfLeadingSpaces(editor: TextEditor | undefined): number {
let numSpaces: number = 0;
/* Helper Function
* This function returns the text from the current line of the active text editor window
*/
function fetchTextLine(editor: TextEditor): vscode.TextLine|undefined {
return editor? editor.document.lineAt(fetchLineNumber(editor) - 1): undefined;
}
// Function that outputs the current line number the cursor is on
function getLineNumber(): void {
const editor: TextEditor = vscode.window.activeTextEditor;
if (editor) {
const lineNum: number = fetchLineNumber(editor);
/*
* 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: boolean = false; // change boolean value to change method
const line : TextLine = fetchLine(editor);
vscode.window.showInformationMessage(`Line ${lineNum.toString()}`);
/* If true, calculate by arithmetic otherwise get index */
numSpaces = (calculateLeadingSpaces)
? pl.Lexer.getLeadingSpacesByArithmetic(line)
: pl.Lexer.getLeadingSpacesByIndex(line);
}
return numSpaces;
}
/** Helper Function
* * This function returns the number of selected lines in the active text editor window
@param editor
@returns numberOfSelectedLines
*/
function fetchNumberOfSelectedLines(editor: TextEditor | undefined): number {
let numberOfSelectedLines: number = 0;
if (editor) {
numberOfSelectedLines = editor.selections.reduce((prev, curr) => prev + (curr.end.line - curr.start.line), 1);
}
return numberOfSelectedLines;
}
/** Helper Function
** This function returns the line number of the active text editor window
* @param editor
* @returns editor!.selection.active.line + 1
*/
function fetchLineNumber(editor: TextEditor | undefined): number {
return editor!.selection.active.line + 1; // line numbers start at 1, not 0, so we add 1 to the result
}
/** Helper Function
** This function returns the text from the current line of the active text editor window
* @param editor
* @returns editor.document.lineAt(fetchLineNumber(editor) - 1)
*/
function fetchLine(editor: TextEditor | undefined): TextLine {
return editor!.document.lineAt(fetchLineNumber(editor) - 1); // We want the line index, so we remove the 1 we added to the result in fetchLineNumber
}
/* Function
* Function to return the number of selected (highlighted) lines
* Changes output to 'Line' for 1 line and 'Lines' for all other instances
*/
function getNumberOfSelectedLines(): void {
const editor: TextEditor | undefined = window.activeTextEditor;
if (editor) {
const numberOfSelectedLines: number = fetchNumberOfSelectedLines(editor);
(numberOfSelectedLines !== 1)
? window.showInformationMessage(`${numberOfSelectedLines.toString()} Lines Selected`)
: window.showInformationMessage(`${numberOfSelectedLines.toString()} Line Selected`);
window.showTextDocument(editor.document); // After the selection is made, the editor loses focus. We need to re-focus the editor so typing isn't interrupted
}
else {
vscode.window.showErrorMessage('No document currently active');
window.showErrorMessage('No document currently active');
}
}
function getIndent(): void {
const editor: TextEditor = vscode.window.activeTextEditor;
/* Function
* Outputs the current line number the cursor is on
*/
function getLineNumber(): void {
const editor: TextEditor | undefined = window.activeTextEditor;
if (editor) {
const lineNum: number = fetchLineNumber(editor);
const textLine: vscode.TextLine = editor.document.lineAt(lineNum - 1);
if (textLine.isEmptyOrWhitespace) {
vscode.window.showInformationMessage(`Line ${lineNum.toString()} is Empty`);
window.showInformationMessage(`Line ${lineNum.toString()}`);
window.showTextDocument(editor.document); // After the selection is made, the editor loses focus. We need to re-focus the editor so typing isn't interrupted
}
else {
window.showErrorMessage('No document currently active');
}
}
/* Function
* Used to get the number of indents on a line
*/
function getIndent(): void {
const editor: TextEditor | undefined = window.activeTextEditor;
if (editor) {
const lineNum: number = (fetchLineNumber(editor));
const line : TextLine = fetchLine(editor);
if (line.isEmptyOrWhitespace) {
window.showInformationMessage(`Line ${lineNum.toString()} is Empty`);
}
else {
// Grab tab format from open document
@@ -72,77 +166,99 @@ function getIndent(): void {
size: typeof editor.options.tabSize === 'number'? editor.options.tabSize: 4,
hard: !editor.options.insertSpaces
};
const i: number = pl.Lexer.getIndent(textLine.text, tabFmt);
const i: number = pl.Lexer.getIndent(line.text, tabFmt);
vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indents`);
(i !== 1)
? window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indents`)
: window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indent`);
}
window.showTextDocument(editor.document); // After the selection is made, the editor loses focus. We need to re-focus the editor so typing isn't interrupted
}
else {
vscode.window.showErrorMessage('No document currently active');
window.showErrorMessage('No document currently active');
}
}
/* Function -> Returns the number of leading spaces on the line the cursor is on
* 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
* Returns the number of leading spaces on the line the cursor is on
*/
function getLeadingSpaces(): void {
const editor: any = vscode.window.activeTextEditor;
const editor: TextEditor | undefined = window.activeTextEditor;
if (editor) {
const lineNum: number = fetchLineNumber(editor);
const textLine: vscode.TextLine|undefined = fetchTextLine(editor);
// If there's no line, or the line is empty, say the line is empty
if (!textLine || textLine.isEmptyOrWhitespace) {
vscode.window.showInformationMessage(`Line ${lineNum.toString()} is empty`);
const lineNum : number = fetchLineNumber(editor);
const line : TextLine | undefined = fetchLine(editor);
if (line.isEmptyOrWhitespace) {
window.showInformationMessage(`Line ${lineNum.toString()} is empty`);
}
else {
/*
* 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: boolean = false; // change boolean value to change method
const numSpaces: number = (calculateLeadingSpaces) ?
pl.Lexer.getLeadingSpacesByArithmetic(textLine) :
pl.Lexer.getLeadingSpacesByIndex(textLine);
const numSpaces = fetchNumberOfLeadingSpaces(editor);
/* Ternary operator to change the tense of 'space' to 'spaces' for the output if numSpaces is 0 or greater than 1 */
(numSpaces !== 1) ?
vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} spaces`):
vscode.window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} space`);
(numSpaces !== 1)
? window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} spaces`)
: window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} space`);
}
window.showTextDocument(editor.document); // After the selection is made, the editor loses focus. We need to re-focus the editor so typing isn't interrupted
}
else {
vscode.window.showErrorMessage('No document currently active');
window.showErrorMessage('No document currently active');
}
}
/* Function
* Selects the leading whitespace at the beginning of a line
* This feature was a request from Senior Design Day Spring 2022
*/
function selectLeadingWhitespace(): void {
const editor : TextEditor | undefined = window.activeTextEditor;
if (editor) {
const numSpaces = fetchNumberOfLeadingSpaces(editor); // This will be used for the output message
const lineNum : number = (fetchLineNumber(editor)); // Get the displayed line number
/* If numSpaces isn't greater than 1, then there is no leading whitespace to select */
if (numSpaces >= 1) {
const line : TextLine = fetchLine(editor);
const startPos: number = line.range.start.character; // Start at the starting character position
const endPos : number = line.firstNonWhitespaceCharacterIndex; // End at the first non whitespace character index
/* Apply our selection */
/* We need to subtract 1 from lineNum because we added 1 during the fetchLineNumber above and we want the 0-index for position, so remove it */
editor.selection = new Selection(new Position((lineNum - 1), startPos), new Position((lineNum - 1), endPos));
/* Ternary operator to change the tense of 'space' to 'spaces' for the output if numSpaces is 0 or greater than 1 */
(numSpaces !== 1)
? window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} spaces selected`)
: window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} space selected`);
}
else {
window.showErrorMessage(`Line ${lineNum.toString()}: No leading spaces to select!`); // No whitespace to select
}
window.showTextDocument(editor.document); // After the selection is made, the editor loses focus. We need to re-focus the editor so typing isn't interrupted
}
else {
window.showErrorMessage('No document currently active'); // No active document
}
}
function runLineContext(): void {
const editor: TextEditor = vscode.window.activeTextEditor;
const editor: TextEditor | undefined = window.activeTextEditor;
if (editor) {
// current text and line number
const editorText: string = editor.document.getText();
const line: number = editor.selection.active.line;
const editorText: string = editor.document.getText();
const line : number = editor.selection.active.line;
// get tab info settings
const size: number = typeof editor.options.tabSize === 'number'? editor.options.tabSize: 4;
const hard: boolean = !editor.options.insertSpaces;
const size : number = typeof editor.options.tabSize === 'number'? editor.options.tabSize: 4;
const hard : boolean = !editor.options.insertSpaces;
// initialize parser
const parser: pl.Parser = new pl.Parser(editorText, {
const parser : pl.Parser = new pl.Parser(editorText, {
size,
hard
});
@@ -152,10 +268,10 @@ function runLineContext(): void {
// build text
const contentString: string = createContextString(context, line);
vscode.window.showInformationMessage(contentString);
window.showInformationMessage(contentString);
}
else {
vscode.window.showErrorMessage('No document currently active');
window.showErrorMessage('No document currently active');
}
}
@@ -186,8 +302,8 @@ function createContextString(context: pl.LexNode[], line: number): string {
// Node is the document root
if (node.label === 'root') {
// Append the name (relative path) of the document in the workspace
if (vscode.window.activeTextEditor?.document.uri) {
contextString += ` ${inside} ${vscode.workspace.asRelativePath(vscode.window.activeTextEditor?.document.uri)}`;
if (window.activeTextEditor?.document.uri) {
contextString += ` ${inside} ${workspace.asRelativePath(window.activeTextEditor?.document.uri)}`;
} else {
contextString += ` ${inside} the Document`;
}
@@ -198,25 +314,27 @@ function createContextString(context: pl.LexNode[], line: number): string {
return contextString;
}
// find up to `n` words around the cursor, where `n` is
// the value of `#mindReader.reader.contextWindow`
/*
* find up to `n` words around the cursor, where `n` is
* the value of `#mindReader.reader.contextWindow`
*/
function runCursorContext(): void {
const editor: vscode.TextEditor | undefined = vscode.window.activeTextEditor;
const editor: TextEditor | undefined = window.activeTextEditor;
if (!editor) {
vscode.window.showErrorMessage('RunCursorContext: No Active Editor');
window.showErrorMessage('RunCursorContext: No Active Editor');
return;
}
const cursorPos: vscode.Position = editor.selection.active;
const text: string = editor.document.lineAt(cursorPos).text;
const windowSize: any = vscode.workspace.getConfiguration('mindReader').get('reader.contextWindow');
let trimmedText: string = text.trimStart(); // trim leading whitespace
const leadingWS: number = text.length - trimmedText.length; // # of characters of leading whitespace
let pos: number = leadingWS;
const maxPos: number = text.length;
const cursorPos : Position = editor.selection.active;
const text : string = editor.document.lineAt(cursorPos).text;
const windowSize : any = workspace.getConfiguration('mindReader').get('reader.contextWindow');
let trimmedText: string = text.trimStart(); // trim leading whitespace
const leadingWS : number = text.length - trimmedText.length; // # of characters of leading whitespace
let pos : number = leadingWS;
const maxPos : number = text.length;
// clamp cursor start/end to new range
let col: number = cursorPos.character; // effective column of the cursor position
let col : number = cursorPos.character; // effective column of the cursor position
trimmedText = trimmedText.trimEnd(); // trim trailing whitespace
@@ -251,7 +369,7 @@ function runCursorContext(): void {
// find word the user is in
let contextStart: number = -1;
let contextEnd: number = -1;
let contextEnd : number = -1;
for (let i: number = 0; i < spaceWords.length; i++) {
if (col >= spaceWords[i].start && col <= spaceWords[i].end) {
@@ -265,7 +383,7 @@ function runCursorContext(): void {
contextString += spaceWords[i].word + ' ';
}
// output cursor context string
vscode.window.showInformationMessage(contextString);
window.showInformationMessage(contextString);
return;
}
}

View File

@@ -1,49 +1,47 @@
import * as vscode from 'vscode';
import * as pl from './pylex';
import * as vscode from "vscode";
import * as pl from "./pylex";
import CommandNodeProvider from "./commandNodeProvider";
import Logger from "./log";
import { lineHighlighter } from "./lineHighlighter";
import {
accessCommands,
hubCommands,
navCommands,
textCommands
} from './commands';
import CommandNodeProvider from './commandNodeProvider';
import Logger from './log';
import { accessCommands, hubCommands, navCommands, textCommands } from "./commands";
// Output Logger
const product: string = vscode.workspace.getConfiguration('mindReader').get('productType')!;
const outputChannel = vscode.window.createOutputChannel(product + " Output");
export const logger = new Logger(outputChannel);
const product: string = vscode.workspace.getConfiguration("mindReader").get("productType")!;
const outputChannel = vscode.window.createOutputChannel(product + " Output");
export const logger = new Logger(outputChannel);
let parser: pl.Parser = new pl.Parser();
export function activate(context: vscode.ExtensionContext) {
vscode.window.showInformationMessage('Mind_Reader is loaded!');
// Engage LineHighlighter
lineHighlighter();
parser.parse('Beep Boop');
parser.parse("Beep Boop");
const allCommands = [
accessCommands,
hubCommands,
navCommands,
textCommands
textCommands,
].flat(1);
// Register Commands
allCommands.forEach(command => {
let disposable = vscode.commands.registerCommand(
command.name,
command.callback
allCommands.forEach((command) => {
context.subscriptions.push(
vscode.commands.registerCommand(command.name, command.callback)
);
context.subscriptions.push(disposable);
});
let accessProvider = new CommandNodeProvider([accessCommands, textCommands].flat(1));
vscode.window.registerTreeDataProvider('accessActions', accessProvider);
let accessProvider = new CommandNodeProvider(
[accessCommands, textCommands].flat(1)
);
vscode.window.registerTreeDataProvider("accessActions", accessProvider);
let hubProvider = new CommandNodeProvider(hubCommands);
vscode.window.registerTreeDataProvider('hubActions', hubProvider);
vscode.window.registerTreeDataProvider("hubActions", hubProvider);
vscode.window.showInformationMessage("Mind Reader finished loading!");
}
export function deactivate() {}

274
src/lineHighlighter.ts Normal file
View File

@@ -0,0 +1,274 @@
/**
* ? ██╗ ██╗██╗ ██████╗ ██╗ ██╗██╗ ██╗ ██████╗ ██╗ ██╗████████╗ ██╗████████╗
* ? ██║ ██║██║██╔════╝ ██║ ██║██║ ██║██╔════╝ ██║ ██║╚══██╔══╝ ██║╚══██╔══╝
* ? ███████║██║██║ ███╗███████║██║ ██║██║ ███╗███████║ ██║ █████╗██║ ██║
* ? ██╔══██║██║██║ ██║██╔══██║██║ ██║██║ ██║██╔══██║ ██║ ╚════╝██║ ██║
* ? ██║ ██║██║╚██████╔╝██║ ██║███████╗██║╚██████╔╝██║ ██║ ██║ ██║ ██║
* ? ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
* TODO: Add ability for user to change options through a command pallette configurator
**/
'use strict';
import { Position, window, workspace, TextEditorDecorationType, TextEditor, WorkspaceConfiguration, Range } from 'vscode';
export { lineHighlighter };
let highlightStyle: TextEditorDecorationType;
function lineHighlighter(): void {
let highlightStyle : TextEditorDecorationType = getHighlighterStyle();
let activeTextEditor : TextEditor | undefined = window.activeTextEditor;
let isEnabled : boolean | undefined = getHighlighterStatus();
let multiLineIsEnabled: boolean | undefined = getMultiLineHighlighterStatus();
/**
* Trigger the line highlight when the extension loads so current line gets highlighted
*/
triggerHighlight();
/**
* Trigger for when the active text editor changes
*/
window.onDidChangeActiveTextEditor((editor) => {
if (!editor) {
return;
}
triggerHighlight();
});
/**
* Trigger for when text selection changes
*/
window.onDidChangeTextEditorSelection((editor) => {
if (!editor.textEditor) {
return;
}
triggerHighlight();
});
/**
* Trigger for when the text document changes
*/
workspace.onDidChangeTextDocument(() => {
if (!activeTextEditor) {
return;
}
triggerHighlight();
});
/**
* Trigger for when the window state changes
*/
window.onDidChangeWindowState((editor) => {
if (!editor) {
return;
}
triggerHighlight();
});
/**
* Trigger for when configuration changes
*/
workspace.onDidChangeConfiguration((editor) => {
if (!editor) {
return;
}
highlightStyle.dispose(); // Dump existing styling
isEnabled = getHighlighterStatus(); // check if line highlighter is enable/disabled
multiLineIsEnabled = getMultiLineHighlighterStatus(); // Check if multiline highlighting is enabled/disabled
highlightStyle = getHighlighterStyle(); // get new line highlighter styling
triggerHighlight(); // trigger highlight with new styling
});
/**
* main function that triggers the highlights
*/
function triggerHighlight(): void {
if (!activeTextEditor) {
return;
}
/**
* Sets the activeTextEditor to the current active window
*/
activeTextEditor = window.activeTextEditor;
if (activeTextEditor !== undefined) {
/**
* If the line highlighter function is enabled
* set the decorations with our chosen highlighting style on the selection
* otherwise (highlighter is disabled) dump our highlighting style
*/
switch (isEnabled) {
case true: /* isEnabled is true */
switch (multiLineIsEnabled) {
case true: /* isEnabled is true and multiLineIsEnabled is true */
activeTextEditor.setDecorations(highlightStyle, activeTextEditor.selections);
break;
case false: /* isEnabled is true and multiLineIsEnabled is false */
switch (activeTextEditor.selection.isSingleLine) {
case true: /* isEnabled is true and multiLineIsEnabled is false and VSCode is reporting a single line */
let currentPosition = [];
for (let i = 0; i < activeTextEditor.selections.length; i++) {
currentPosition[i] = { range: new Range(activeTextEditor.selections[i].anchor, activeTextEditor.selections[i].anchor) };
}
activeTextEditor.setDecorations(highlightStyle, currentPosition);
break;
case false: /* isEnabled is true and multiLineIsEnabled is false and VSCode is reporting multiple lines */
// Dispose of our highlighting style so multiple lines aren't all highlighted when clicking and dragging to highlight
activeTextEditor.setDecorations(highlightStyle, []); // This will dispose of a single editor instead of all editors
break;
default: /* isEnabled is true and multiLineIsEnabled is false and VSCode is reporting something else - break out of 3rd switch */
break;
}
break;
default: /* isEnabled is true and multiLineIsEnabled is undetected - break out of 2nd switch statement */
break;
}
break;
case false: /* isEnabled is false */
highlightStyle.dispose();
break;
default: /* break out of initial switch if 'true or false' is not found */
break;
}
// Keep track of position
new Position(activeTextEditor.selection.start.line, activeTextEditor.selection.start.character);
}
}
/**
* * Function to get the user configured highlighting styles, or use defaults
*
* * Designed with user configuration in mind, able to control different sides
* * independently from each other (in most cases). This allows for many different
* * configurations.
*
* ? Colors Can be input with the following values:
* * https://www.w3schools.com/cssref/css_colors.asp for string based color values
* * Hex -> #<value> | rgb(###, ###, ###) | rgba(###, ###, ###, ###) | hsla(##, ##%, ##%, .#)
*
* ? Width Input Values
* ! Some work better than others, if one isn't working try a different method:
* * thin | medium | thick | px | rem | em | cm
*
* ? Other values
* * font-style : none|normal|italic|oblique;
* * font-weight : none|normal|bold|bolder|lighter|number;
* * border-style : none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset;
* * outline-style : none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset;
* * outline-width : none|medium|thin|thick|length;
* * border-width : none|medium|thin|thick|length;
* ? https://www.w3schools.com/cssref/pr_text_text-decoration.asp for text-decoration
*
* ! borderWidthRight acts weirdly, on my system 16px works best with the other directions set to 1px
*
* @returns highlighterStyle
*/
function getHighlighterStyle(): TextEditorDecorationType {
// Used so we don't have to type out workspace.getConfiguration('mind-reader.lineHighlighter') on every line, ie: shorthand
const userConfig: WorkspaceConfiguration = workspace.getConfiguration('mind-reader.lineHighlighter');
const borderWidthTop : string = userConfig.get('borderWidthTop') || "1px";
const borderWidthRight : string = userConfig.get('borderWidthRight') || "16px";
const borderWidthBottom : string = userConfig.get('borderWidthBottom') || "1px";
const borderWidthLeft : string = userConfig.get('borderWidthLeft') || "1px";
const borderStyleTop : string = userConfig.get('borderStyleTop') || "solid";
const borderStyleRight : string = userConfig.get('borderStyleRight') || "solid";
const borderStyleBottom : string = userConfig.get('borderStyleBottom') || "solid";
const borderStyleLeft : string = userConfig.get('borderStyleLeft') || "solid";
const borderColorTop : string = userConfig.get('borderColorTop') || "#FFFFFF";
const borderColorRight : string = userConfig.get('borderColorRight') || "#FFFFFF";
const borderColorBottom : string = userConfig.get('borderColorBottom') || "#FFFFFF";
const borderColorLeft : string = userConfig.get('borderColorLeft') || "#FFFFFF";
const backgroundColor : string = userConfig.get('backgroundColor') || "#232C5C";
const fontStyle : string = userConfig.get('fontStyle') || "normal";
const fontWeight : string = userConfig.get('fontWeight') || "bolder";
const outlineColor : string = userConfig.get('outlineColor') || "#4866FE";
const outlineStyle : string = userConfig.get('outlineStyle') || "solid";
const outlineWidth : string = userConfig.get('outlineWidth') || "1px";
const textDecoration : string = userConfig.get('textDecoration') || "none";
const textColor : string = userConfig.get('textColor') || "#FFFFFF";
// Combine all our styling into a single variable to return
const highlighterStyle : TextEditorDecorationType = window.createTextEditorDecorationType({
isWholeLine : true,
backgroundColor : `${backgroundColor}`,
fontStyle : `${fontStyle}`,
fontWeight : `${fontWeight}`,
textDecoration : `${textDecoration}`,
color : `${textColor}`,
borderColor : `${borderColorTop} ${borderColorRight} ${borderColorBottom} ${borderColorLeft}`,
borderWidth : `${borderWidthTop} ${borderWidthRight} ${borderWidthBottom} ${borderWidthLeft}`,
borderStyle : `${borderStyleTop} ${borderStyleRight} ${borderStyleBottom} ${borderStyleLeft}`,
outlineColor : `${outlineColor}`,
outlineWidth : `${outlineWidth}`,
outlineStyle : `${outlineStyle}`,
});
// Return our variable
return highlighterStyle;
}
/**
* Function to retrieve the 'isEnabled' status
*
* This will determine if the line highlighter will display or not
* - enabled -> will show
* - disabled -> will not show
*
* @returns enabledStatus
*/
function getHighlighterStatus(): boolean | undefined {
// set a boolean variable
let enabledStatus: boolean | undefined;
/***
* if "isEnabled" is missing from the settings (aka undefined)
* - set our variable to true (default)
* otherwise, "isEnabled" is listed in the settings
* - so we just pull its value
*/
(workspace.getConfiguration("mind-reader.lineHighlighter").get("isEnabled") === undefined)
? (enabledStatus = true)
: (enabledStatus = workspace.getConfiguration("mind-reader.lineHighlighter").get("isEnabled"));
// return the enabledStatus
return enabledStatus;
}
function getMultiLineHighlighterStatus(): boolean | undefined {
// set a boolean variable
let multiLineIsEnabled: boolean | undefined;
/***
* if "isEnabled" is missing from the settings (aka undefined)
* - set our variable to true (default)
* otherwise, "isEnabled" is listed in the settings
* - so we just pull its value
*/
(workspace.getConfiguration("mind-reader.lineHighlighter").get("multiLineIsEnabled") === undefined)
? (multiLineIsEnabled = true)
: (multiLineIsEnabled = workspace.getConfiguration("mind-reader.lineHighlighter").get("multiLineIsEnabled"));
// return the enabledStatus
return multiLineIsEnabled;
}
}
// Clean-up after ourself
export function deactivate() {
// when the plugin is terminated remove all highlighting
if (highlightStyle !== undefined) {
highlightStyle.dispose();
}
}

View File

@@ -1,9 +1,9 @@
import { LineToken } from '.';
import { LineToken } from '.';
import { Symbol, EOFTOKEN, TabInfo } from './token';
type Rule = {
pattern: RegExp,
type: Symbol,
type : Symbol,
};
/**
@@ -11,8 +11,7 @@ type Rule = {
* The first item is a recognition pattern, used to recognize the token
* the second item is the token type
*/
const rules: Rule[] = [
{
const rules: Rule[] = [{
pattern: /^\s*def\s+(?<attr>[a-zA-Z_][a-zA-Z0-9_]*)\(/,
type: Symbol.FUNCTION
},
@@ -74,8 +73,8 @@ const rules: Rule[] = [
* Line-By-Line Lexer
*/
export default class Lexer {
private textLines: string[] = []; // array of text lines
private pos: number = 0;
private textLines : string[] = []; // array of text lines
private pos : number = 0;
private _currToken: LineToken = EOFTOKEN;
/**
@@ -105,8 +104,8 @@ export default class Lexer {
* @param `text` The new text to lex.
*/
restart(text ? : string): void {
this.pos = 0;
this._currToken = EOFTOKEN; // if no input, already on EOFTOKEN
this.pos = 0;
this._currToken = EOFTOKEN; // if no input, already on EOFTOKEN
if (text) {
this.textLines = text.split('\n');
this.next(); // advance to the first token
@@ -132,9 +131,9 @@ export default class Lexer {
// Until a LineToken is found, or EOF
while (this.pos < this.textLines.length) {
const line: string = this.textLines[this.pos];
const line : string = this.textLines[this.pos];
const indent: number = Lexer.getIndent(line, this.tabFmt!);
let token: LineToken;
let token : LineToken;
for (var r of rules) {
// Does line match pattern?
@@ -143,8 +142,7 @@ export default class Lexer {
// Yes...
if (match.groups) {
token = new LineToken(r.type, this.pos, indent, match.groups["attr"]);
}
else {
} else {
token = new LineToken(r.type, this.pos, indent);
}