mirror of
https://github.com/We-Dont-Byte/Mind_Reader.git
synced 2025-01-18 10:36:11 +00:00
Merge pull request #4 from We-Dont-Byte/merge-johnbreaux-thomaslane
Merge "merge-johnbreaux-thomaslane" into "master" This includes breaking changes! See pull request #4 for list of changes.
This commit is contained in:
commit
0a39522eca
15
.github/workflows/vscode-test.yaml
vendored
15
.github/workflows/vscode-test.yaml
vendored
@ -10,15 +10,22 @@ jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11, ubuntu-latest, windows-latest]
|
||||
os:
|
||||
- macos-11
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
node_version:
|
||||
- 16
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 10.x
|
||||
node-version: ${{ matrix.node_version }}
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
- run: npm ci
|
||||
- run: xvfb-run -a npm test
|
||||
if: runner.os == 'Linux'
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,4 +2,5 @@ out
|
||||
dist
|
||||
node_modules
|
||||
.vscode-test/
|
||||
*.code-workspace
|
||||
*.vsix
|
||||
|
12
README.md
12
README.md
@ -3,7 +3,7 @@
|
||||
<img alt="Mind Reader Logo" src="media/logo.png"></img>
|
||||
</p>
|
||||
|
||||
<h1>Mind_Reader</h1>
|
||||
<h1>Mind Reader</h1>
|
||||
|
||||
<!-- overview description -->
|
||||
|
||||
@ -42,7 +42,7 @@ Python programming with LEGO Mindstorms. Our goal is to:
|
||||
<img width="50%" height="50%" alt="tools for native modules page with tool installation checked" src="media/nodejs_setup.png"></img>
|
||||
</p>
|
||||
|
||||
If the compiled serial port version is incompatible, you may see no options presented in the Mind_Reader actions panel:
|
||||
If the compiled serial port version is incompatible, you may see no options presented in the Mind Reader actions panel:
|
||||
|
||||
<p align="center">
|
||||
<img width="50%" height="50%" alt="mind reader actions panel with no items:" src="media/missing_actions.png"></img>
|
||||
@ -73,7 +73,7 @@ The electron version should be listed, e.g.: `Electron: 13.5.2`
|
||||
<img width="35%" height="35%" alt="vscode information" src="media/vscode_info.png"></img>
|
||||
</p>
|
||||
|
||||
### 3 Finding the Mind_Reader extension directory
|
||||
### 3 Finding the Mind Reader extension directory
|
||||
On MacOS and Linux this is `~/.vscode/extensions`.
|
||||
|
||||
On Windows this is `C:\<YOUR USER>\.vscode\extensions\`. However, in Git Bash, it will appear like on MacOS and Linux
|
||||
@ -81,7 +81,7 @@ e.g.: `~/.vscode/extensions`.
|
||||
|
||||
---
|
||||
|
||||
Find the Mind_Reader extension folder, this should look like `xxx.mind-reader-x.x.x`.
|
||||
Find the Mind Reader extension folder, this should look like `xxx.mind-reader-x.x.x`.
|
||||
|
||||
Navigate to the found folder in the terminal.
|
||||
|
||||
@ -102,8 +102,8 @@ $ electron-rebuild --version=ELECTRON_VERSION
|
||||
Use the following to set up the extension for development.
|
||||
|
||||
```console
|
||||
$ git clone https://github.com/SingleSemesterSnobs/Mind_Reader.git
|
||||
$ cd Mind_Reader
|
||||
$ git clone https://github.com/SingleSemesterSnobs/Mind Reader.git
|
||||
$ cd Mind Reader
|
||||
$ npm install
|
||||
```
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<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>
|
||||
<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>
|
||||
|
42
package-lock.json
generated
42
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "mind-reader",
|
||||
"version": "0.0.1",
|
||||
"version": "2.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mind-reader",
|
||||
"version": "0.0.1",
|
||||
"version": "2.0.0",
|
||||
"dependencies": {
|
||||
"serialport": "^9.2.5"
|
||||
},
|
||||
@ -26,7 +26,7 @@
|
||||
"vscode-test": "^1.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.60.0"
|
||||
"vscode": "^1.66.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@ -2101,9 +2101,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "0.5.5",
|
||||
@ -2817,9 +2817,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/simple-get": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
|
||||
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
|
||||
"dependencies": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"once": "^1.3.1",
|
||||
@ -3205,9 +3205,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align/node_modules/ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
|
||||
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@ -4896,9 +4896,9 @@
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
@ -5405,9 +5405,9 @@
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
|
||||
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
|
||||
"requires": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"once": "^1.3.1",
|
||||
@ -5715,9 +5715,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
|
||||
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
|
550
package.json
550
package.json
@ -1,10 +1,56 @@
|
||||
{
|
||||
"name": "mind-reader",
|
||||
"displayName": "Mind_Reader",
|
||||
"repository": "https://github.com/SingleSemesterSnobs/Mind_Reader",
|
||||
"version": "1.0.0",
|
||||
"displayName": "Mind Reader",
|
||||
"homepage": "https://github.com/We-Dont-Byte/Mind_Reader/wiki",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/We-Dont-Byte/Mind_Reader"
|
||||
},
|
||||
"bugs": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/We-Dont-Byte/Mind_Reader/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name" : "Jake Grossman",
|
||||
"email" : "JacobGrossman2@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "Cal Wooten",
|
||||
"email" : "calwooten@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "Josiah Mosesn",
|
||||
"email" : "josiahmoses@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "Sophia Drewfs",
|
||||
"email" : "sophiadrewfs@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "John Breaux",
|
||||
"email" : "JohnBreaux@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "Thomas Lane",
|
||||
"email" : "ThomasLane2@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "Ryan Tolbert",
|
||||
"email" : "RyanTolbert@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "Kendrick Johnson",
|
||||
"email" : "KendrickJohnson@my.unt.edu"
|
||||
},
|
||||
{
|
||||
"name" : "Pedro Alvarez",
|
||||
"email" : "PedroAlvarez3@my.unt.edu"
|
||||
}
|
||||
],
|
||||
"version": "2.0.0",
|
||||
"engines": {
|
||||
"vscode": "^1.60.0"
|
||||
"vscode": "^1.66.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
@ -15,199 +61,249 @@
|
||||
"main": "./out/extension.js",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "mind-reader.helloWorld",
|
||||
"title": "Hello World"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.increaseFontScale",
|
||||
"title": "Increase Font Scale"
|
||||
"title": "Increase Font Scale",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.decreaseFontScale",
|
||||
"title": "Decrease Font Scale"
|
||||
"title": "Decrease Font Scale",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.resetFontScale",
|
||||
"title": "Reset Font Scale"
|
||||
"title": "Reset Font Scale",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.increaseEditorScale",
|
||||
"title": "Increase Editor Scale"
|
||||
"title": "Increase Editor Scale",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.decreaseEditorScale",
|
||||
"title": "Decrease Editor Scale"
|
||||
"title": "Decrease Editor Scale",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.resetEditorScale",
|
||||
"title": "Reset Editor Scale"
|
||||
"title": "Reset Editor Scale",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.selectTheme",
|
||||
"title": "Select Theme"
|
||||
"title": "Select Theme",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openWebview",
|
||||
"title": "Mind Reader Webview"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openKeyBindWin",
|
||||
"title": "Key Bindings for Windows"
|
||||
"command": "mind-reader.openKeybinds",
|
||||
"title": "Edit Keybinds",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openKeyBindMac",
|
||||
"title": "Key Bindings for Mac"
|
||||
"command": "mind-reader.getLineScope",
|
||||
"title": "Get Scope of the Current Line",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.runLineContext",
|
||||
"title": "Run Line Context"
|
||||
"command": "mind-reader.getWordsUnderCursor",
|
||||
"title": "Get Words Under the Cursor",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.runCursorContext",
|
||||
"title": "Run Cursor Context"
|
||||
"command": "mind-reader.getLineNumber",
|
||||
"title": "Get The Current Line Number"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getIndent",
|
||||
"title": "Get Line Indentation"
|
||||
"title": "Get The Number Of Line Indentations"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getLeadingSpaces",
|
||||
"title": "Get The Number Of Leading Spaces"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.selectLeadingWhitespace",
|
||||
"title": "Select The Leading Whitespace"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getNumberOfSelectedLines",
|
||||
"title": "Get The Number Of Selected Lines"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.connectHub",
|
||||
"title": "Connect LEGO Hub"
|
||||
"title": "Connect LEGO SPIKE Prime Hub",
|
||||
"category": "SPIKE Prime"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.disconnectHub",
|
||||
"title": "Disconnect LEGO Hub"
|
||||
"title": "Disconnect LEGO SPIKE Prime Hub",
|
||||
"category": "SPIKE Prime"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.uploadCurrentFile",
|
||||
"title": "Upload current file to LEGO Hub"
|
||||
"title": "Upload Current File to LEGO SPIKE Prime Hub",
|
||||
"category": "SPIKE Prime"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.runProgram",
|
||||
"title": "Run a program from the LEGO Hub"
|
||||
"title": "Run a Program on the LEGO SPIKE Prime Hub",
|
||||
"category": "SPIKE Prime"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.stopExecution",
|
||||
"title": "Stop running program on the LEGO Hub"
|
||||
"title": "Stop Running Program on the LEGO SPIKE Prime Hub",
|
||||
"category": "SPIKE Prime"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.deleteProgram",
|
||||
"title": "Delete a program from the LEGO Hub"
|
||||
"title": "Delete a Program from the LEGO SPIKE Prime Hub",
|
||||
"category": "SPIKE Prime"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.uploadCurrentFile",
|
||||
"title": "Upload Current File to the LEGO SPIKE Prime Hub",
|
||||
"category": "SPIKE Prime"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getLeadingSpaces",
|
||||
"title": "Get Leading Spaces",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getLineNumber",
|
||||
"title": "Get Line Number",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getQuickInputBack",
|
||||
"title": "Go Back in Quick Input",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.gotoLine",
|
||||
"title": "Go to Line",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.gotoSymbol",
|
||||
"title": "Go to Symbol",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.navigateBack",
|
||||
"title": "Navigate Backward",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.navigateForward",
|
||||
"title": "Navigate Forward",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.nextInFiles",
|
||||
"title": "Go to Next Problem in Files (Error, Warning, Info)",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.prevInFiles",
|
||||
"title": "Go to Previous Problem in Files (Error, Warning, Info)",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.quickOpen",
|
||||
"title": "Go to File...",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.quickOpenPreviousRecentlyUsedEditorInGroup",
|
||||
"title": "View: Quick Open Previous Recently Used Editor in Group"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.showAllSymbols",
|
||||
"title": "Go to Symbol in Workspace...",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.showProblems",
|
||||
"title": "Show Problems",
|
||||
"category": "Mind Reader"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.showCommands",
|
||||
"title": "Show All Commands",
|
||||
"category": "Mind Reader"
|
||||
}
|
||||
],
|
||||
"keybindings": [
|
||||
{
|
||||
"command": "mind-reader.decreaseFontScale",
|
||||
"key": "numpad_subtract",
|
||||
"mac": "d"
|
||||
"command": "editor.action.fontZoomOut",
|
||||
"key": "Shift+Alt+z -",
|
||||
"when": "editorTextFocus && config.mind-reader.reader.screenReader != JAWS"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.increaseFontScale",
|
||||
"key": "numpad_add",
|
||||
"mac": "[NumpadAdd]"
|
||||
"command": "editor.action.fontZoomIn",
|
||||
"key": "Shift+Alt+z =",
|
||||
"when": "editorTextFocus && config.mind-reader.reader.screenReader != JAWS"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.increaseEditorScale",
|
||||
"key": "shift+numpad_add",
|
||||
"mac": "Shift+[NumpadAdd]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.decreaseEditorScale",
|
||||
"key": "shift+numpad_subtract",
|
||||
"mac": "Shift+[NumpadSubtract]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.resetEditorScale",
|
||||
"key": "shift+enter",
|
||||
"mac": "Shift+[Enter]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.showAllSymbols",
|
||||
"key": "Ctrl+T",
|
||||
"mac": "Cmd+[KeyT]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.gotoLine",
|
||||
"key": "CTRL+G",
|
||||
"mac": "Cmd+[KeyG]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.quickOpen",
|
||||
"key": "CTRL+P",
|
||||
"mac": "Cmd+[KeyP]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.gotoSymbol",
|
||||
"key": "Ctrl+Shift+O",
|
||||
"mac": "Cmd+Shift+[KeyO]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.showProblems",
|
||||
"key": "Ctrl+Shift+M",
|
||||
"mac": "Cmd+Shift+[KeyM]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.nextInFiles",
|
||||
"key": "F8",
|
||||
"mac": "[F8]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.prevInFiles",
|
||||
"key": "Shift+F8",
|
||||
"mac": "Shift+[F8]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.quickOpenPreviousRecentlyUsedEditorInGroup",
|
||||
"key": "Ctrl+Tab",
|
||||
"mac": "Cmd+[Tab]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.navigateBack",
|
||||
"key": "Ctrl+Alt+-",
|
||||
"mac": "Cmd+Alt+[Minus]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getQuickInputBack",
|
||||
"key": "Ctrl+Alt+-",
|
||||
"mac": "Cmd+Alt+[Minus]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.navigateForward",
|
||||
"key": "Ctrl+Shift+-",
|
||||
"mac": "Cmd+Shift+[Minus]"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.selectTheme",
|
||||
"key": "Ctrl+Shift+1",
|
||||
"mac": "Cmd+Shift+[Digit1]"
|
||||
"command": "editor.action.fontZoomReset",
|
||||
"key": "Shift+Alt+z 0",
|
||||
"when": "editorTextFocus && config.mind-reader.reader.screenReader != JAWS"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getIndent",
|
||||
"key": "Shift+Tab",
|
||||
"mac": "Shift+[Tab]"
|
||||
"key": "Ctrl+Shift+/ I",
|
||||
"mac": "Cmd+Shift+[Slash] I",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openKeyBindWin",
|
||||
"key": "Ctrl+Shift+8",
|
||||
"mac": "Cmd+Shift+8"
|
||||
"command": "mind-reader.getLeadingSpaces",
|
||||
"key": "Ctrl+Shift+/ S",
|
||||
"mac": "Cmd+Shift+[Slash] S",
|
||||
"when": "editorTextFocus",
|
||||
"comment": "Requires python language"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openKeyBindMac",
|
||||
"key": "Ctrl+Shift+9",
|
||||
"mac": "Cmd+Shift+9"
|
||||
"command": "mind-reader.getLineNumber",
|
||||
"key": "Ctrl+Shift+/ L",
|
||||
"mac": "Cmd+Shift+[Slash] L",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getLineScope",
|
||||
"key": "Ctrl+Shift+/ C",
|
||||
"mac": "Cmd+Shift+[Slash] C",
|
||||
"when": "editorTextFocus && editorLangId == python"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openKeybinds",
|
||||
"key": "Ctrl+Shift+/ K",
|
||||
"mac": "Cmd+Shift+[Slash] K"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.ev3.test",
|
||||
"key": "Ctrl+E Ctrl+V"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"editor/context": [
|
||||
{
|
||||
"editor/context": [{
|
||||
"submenu": "mind-reader.editor.context",
|
||||
"group": "mind-reader"
|
||||
}
|
||||
],
|
||||
}],
|
||||
"mind-reader.editor.context": [
|
||||
{
|
||||
"command": "mind-reader.increaseEditorScale",
|
||||
"command": "mind-reader.selectTheme",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.increaseFontScale",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
@ -237,7 +333,27 @@
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.selectTheme",
|
||||
"command": "mind-reader.getLineNumber",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getIndent",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getLeadingSpaces",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.selectLeadingWhitespace",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.getNumberOfSelectedLines",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
@ -247,30 +363,25 @@
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openKeyBindWin",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
},
|
||||
{
|
||||
"command": "mind-reader.openKeyBindMac",
|
||||
"command": "mind-reader.openKeybinds",
|
||||
"group": "mind-reader",
|
||||
"when": "activeEditor"
|
||||
}
|
||||
]
|
||||
},
|
||||
"submenus": [
|
||||
{
|
||||
"submenus": [{
|
||||
"id": "mind-reader.editor.context",
|
||||
"label": "Mind_Reader"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"title": "Mind_Reader",
|
||||
"label": "Mind Reader"
|
||||
}],
|
||||
"configuration": [{
|
||||
"title": "Mind Reader",
|
||||
"order": 0,
|
||||
"properties": {
|
||||
"mindReader.productType": {
|
||||
"mind-reader.productType": {
|
||||
"order": 1,
|
||||
"type": "string",
|
||||
"description": "Specifies the LEGO® product.",
|
||||
"default": "MINDSTORMS EV3",
|
||||
"default": "SPIKE Prime",
|
||||
"enum": [
|
||||
"MINDSTORMS EV3",
|
||||
"SPIKE Prime"
|
||||
@ -280,40 +391,177 @@
|
||||
"LEGO® Education SPIKE™ Prime Set (45678)"
|
||||
]
|
||||
},
|
||||
"mindReader.reader.screenReader": {
|
||||
"mind-reader.reader.screenReader": {
|
||||
"order": 0,
|
||||
"type": "string",
|
||||
"description": "Specifies which screen reader to optimize for.",
|
||||
"default": "NVDA",
|
||||
"enum": [
|
||||
"JAWS",
|
||||
"NVDA",
|
||||
"Orca",
|
||||
"VoiceOver"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"Job Access With Speech (Windows)",
|
||||
"NonVisual Desktop Access (Windows)",
|
||||
"Orca (Linux)",
|
||||
"Apple VoiceOver (macOS)"
|
||||
]
|
||||
},
|
||||
"mindReader.reader.contextWindow": {
|
||||
"mind-reader.reader.contextWindow": {
|
||||
"order": 3,
|
||||
"type": "number",
|
||||
"description": "The number of words around the cursor to use when reading the cursor context",
|
||||
"default": 1
|
||||
},
|
||||
"mindReader.connection.portPath": {
|
||||
"mind-reader.connection.portPath": {
|
||||
"order": 2,
|
||||
"type": "string",
|
||||
"markdownDescription": "The default port to try and establish a connection on."
|
||||
},
|
||||
"mindReader.connection.clearOutputOnRun": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to clear the output each time the program is run",
|
||||
"default": "true"
|
||||
}
|
||||
}
|
||||
},
|
||||
"views": {
|
||||
"MindReader": [
|
||||
{
|
||||
"title": "Line Highlighter [Must Close Settings And RESTART VSCode For The Line Highlighter To Function]",
|
||||
"order": 1,
|
||||
"properties": {
|
||||
"mind-reader.lineHighlighter.isEnabled": {
|
||||
"order": 4,
|
||||
"type": "boolean",
|
||||
"markdownDescription": "Enable/Disable the line highlighter.\n\n\n* `Enabled (our default)`: Checked: Line Highlighter is turned `ON`\n* `Disabled`: Unchecked: Line Highlighter is turned `OFF`\n\n### `NOTE`: You Must Close Settings And RESTART Visual Studio Code For The Line Highlighter To Function\n#### Even If No Changes Were Made",
|
||||
"default": true
|
||||
},
|
||||
"mind-reader.lineHighlighter.multiLineIsEnabled": {
|
||||
"order": 5,
|
||||
"type": "boolean",
|
||||
"markdownDescription": "Temporarily Disable highlighting when highlighting multiple lines.\n\n\n* `Enabled`: Checked: Multiline Highlighting is turned `ON`:\n* * When you click and drag line highlights will be applied to all lines\n* `Disabled (our default)`: Unchecked: Multiline Highlighting is turned `OFF`:\n* * When you click and drag the line highlighter will disable itself then re-enable itself when you click onto a single line.",
|
||||
"default": false
|
||||
},
|
||||
"mind-reader.lineHighlighter.backgroundColor": {
|
||||
"order": 6,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the background color to be used by the line highlighter.\n\nSyntax: _color_ or `transparent`\n\nAvailable color formats include:\n* `HEX(A)`: for Hexadecimal Colors: `#RRGGBB` or `#RRGGBBAA` to add transparency\n* `RGB(A)`: for RGB Colors: `rgb(red, green, blue)` or `rgba(red, green, blue, alpha)`\n* `HSL(A)`: for HSL Colors: `hsl(hue, saturation, lightness)` or `hsla(hue, saturation, lightness, alpha)`\n* `Predefined Color Names`: 140 color names are predefined in the HTML and CSS color specification: `blue`, `red`, `coral`, `brown`, [etc...](https://www.w3schools.com/colors/colors_names.asp)\n* `None`: For no color to be applied: Sometimes VSCode will pull a color from your theme, other times it uses black\n* `#232C5C` is our default",
|
||||
"default": "#232C5C"
|
||||
},
|
||||
"mind-reader.lineHighlighter.outlineColor": {
|
||||
"order": 7,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the outline color to be used by the line highlighter.\n\nSyntax: _color_ or `transparent`\n\nAvailable color formats include:\n* `HEX(A)`: for Hexadecimal Colors: `#RRGGBB` or `#RRGGBBAA` to add transparency\n* `RGB(A)`: for RGB Colors: `rgb(red, green, blue)` or `rgba(red, green, blue, alpha)`\n* `HSL(A)`: for HSL Colors: `hsl(hue, saturation, lightness)` or `hsla(hue, saturation, lightness, alpha)`\n* `Predefined Color Names`: 140 color names are predefined in the HTML and CSS color specification: `blue`, `red`, `coral`, `brown`, [etc...](https://www.w3schools.com/colors/colors_names.asp)\n* `None`: For no color to be applied: Sometimes VSCode will pull a color from your theme, other times it uses black\n* `#4866FE` is our default",
|
||||
"default": "#4866FE"
|
||||
},
|
||||
"mind-reader.lineHighlighter.outlineWidth": {
|
||||
"order": 8,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the outline width to be used by the line highlighter.\n\nSyntax: `medium` or `thin` or `thick` or `length` or `none`\n* `medium`: Specifies a medium outline. (usual default)\n* `thin`: Specifies a thin outline\n* `thick`: Specifies a thick outline\n* `length`: you to define the thickness of the outline in [length](https://www.w3schools.com/cssref/css_units.asp) units.\n* `none`: No outline width will be applied\n* `1px` is our default",
|
||||
"default": "1px"
|
||||
},
|
||||
"mind-reader.lineHighlighter.outlineStyle": {
|
||||
"order": 9,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the outline style to be used by the line highlighter.\n\nSyntax: `none` or `hidden` or `dotted` or `dashed` or `solid` or `double` or `groove` or `ridge` or `inset` or `outset`\n* `none`: No border will be applied (usual default)\n* `hidden`: The same as `none`\n* `dotted`: Dotted border\n* `dashed`: Dashed border\n* `solid (our default)`: Solid border\n* `double`: Double border\n* `groove`: 3D grooved border, depends on the outline-color value.\n* `ridge`: 3D ridged border, depends on the outline-color value.\n* `inset`: 3D inset border, depends on the outline-color value.\n* `outset`: 3D outset border, depends on the outline-color value.",
|
||||
"default": "solid"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderColorTop": {
|
||||
"order": 10,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the top border color to be used by the line highlighter.\n\nSyntax: _color_ or `transparent`\n\nAvailable color formats include:\n* `HEX(A)`: for Hexadecimal Colors: `#RRGGBB` or `#RRGGBBAA` to add transparency\n* `RGB(A)`: for RGB Colors: `rgb(red, green, blue)` or `rgba(red, green, blue, alpha)`\n* `HSL(A)`: for HSL Colors: `hsl(hue, saturation, lightness)` or `hsla(hue, saturation, lightness, alpha)`\n* `Predefined Color Names`: 140 color names are predefined in the HTML and CSS color specification: `blue`, `red`, `coral`, `brown`, [etc...](https://www.w3schools.com/colors/colors_names.asp)\n* `None`: For no color to be applied: Sometimes VSCode will pull a color from your theme, other times it uses black\n* `#FFFFFF` is our default",
|
||||
"default": "#FFFFFF"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderColorRight": {
|
||||
"order": 11,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the right border color to be used by the line highlighter.\n\nSyntax: _color_ or `transparent`\n\nAvailable color formats include:\n* `HEX(A)`: for Hexadecimal Colors: `#RRGGBB` or `#RRGGBBAA` to add transparency\n* `RGB(A)`: for RGB Colors: `rgb(red, green, blue)` or `rgba(red, green, blue, alpha)`\n* `HSL(A)`: for HSL Colors: `hsl(hue, saturation, lightness)` or `hsla(hue, saturation, lightness, alpha)`\n* `Predefined Color Names`: 140 color names are predefined in the HTML and CSS color specification: `blue`, `red`, `coral`, `brown`, [etc...](https://www.w3schools.com/colors/colors_names.asp)\n* `None`: For no color to be applied: Sometimes VSCode will pull a color from your theme, other times it uses black\n* `#FFFFFF` is our default",
|
||||
"default": "#FFFFFF"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderColorBottom": {
|
||||
"order": 12,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the bottom border color to be used by the line highlighter.\n\nSyntax: _color_ or `transparent`\n\nAvailable color formats include:\n* `HEX(A)`: for Hexadecimal Colors: `#RRGGBB` or `#RRGGBBAA` to add transparency\n* `RGB(A)`: for RGB Colors: `rgb(red, green, blue)` or `rgba(red, green, blue, alpha)`\n* `HSL(A)`: for HSL Colors: `hsl(hue, saturation, lightness)` or `hsla(hue, saturation, lightness, alpha)`\n* `Predefined Color Names`: 140 color names are predefined in the HTML and CSS color specification: `blue`, `red`, `coral`, `brown`, [etc...](https://www.w3schools.com/colors/colors_names.asp)\n* `None`: For no color to be applied: Sometimes VSCode will pull a color from your theme, other times it uses black\n* `#FFFFFF` is our default",
|
||||
"default": "#FFFFFF"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderColorLeft": {
|
||||
"order": 13,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the left border color to be used by the line highlighter.\n\nSyntax: _color_ or `transparent`\n\nAvailable color formats include:\n* `HEX(A)`: for Hexadecimal Colors: `#RRGGBB` or `#RRGGBBAA` to add transparency\n* `RGB(A)`: for RGB Colors: `rgb(red, green, blue)` or `rgba(red, green, blue, alpha)`\n* `HSL(A)`: for HSL Colors: `hsl(hue, saturation, lightness)` or `hsla(hue, saturation, lightness, alpha)`\n* `Predefined Color Names`: 140 color names are predefined in the HTML and CSS color specification: `blue`, `red`, `coral`, `brown`, [etc...](https://www.w3schools.com/colors/colors_names.asp)\n* `None`: For no color to be applied: Sometimes VSCode will pull a color from your theme, other times it uses black\n* `#FFFFFF` is our default",
|
||||
"default": "#FFFFFF"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderWidthTop": {
|
||||
"order": 14,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the top border width to be used by the line highlighter.\n\nSyntax: `medium` or `thin` or `thick` or `length` or `none`\n* `medium`: Specifies a medium border. (usual default)\n* `thin`: Specifies a thin border\n* `thick`: Specifies a thick border\n* `length`: you to define the thickness of the border in [length](https://www.w3schools.com/cssref/css_units.asp) units.\n* `none`: No border width will be applied\n* `1px` is our default",
|
||||
"default": "1px"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderWidthRight": {
|
||||
"order": 15,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the right border width to be used by the line highlighter.\n\nSyntax: `medium` or `thin` or `thick` or `length` or `none`\n* `medium`: Specifies a medium border. (usual default)\n* `thin`: Specifies a thin border\n* `thick`: Specifies a thick border\n* `length`: you to define the thickness of the border in [length](https://www.w3schools.com/cssref/css_units.asp) units.\n* `none`: No border width will be applied\n* `16px` is our default\n\n#### \nborderWidthRight exhibits odd behavior, play around with different sizes to find what works best for your environment.",
|
||||
"default": "16px"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderWidthBottom": {
|
||||
"order": 16,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the bottom border width to be used by the line highlighter.\n\nSyntax: `medium` or `thin` or `thick` or `length` or `none`\n* `medium`: Specifies a medium border. (usual default)\n* `thin`: Specifies a thin border\n* `thick`: Specifies a thick border\n* `length`: you to define the thickness of the border in [length](https://www.w3schools.com/cssref/css_units.asp) units.\n* `none`: No border width will be applied\n* `1px` is our default",
|
||||
"default": "1px"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderWidthLeft": {
|
||||
"order": 17,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the left border width to be used by the line highlighter.\n\nSyntax: `medium` or `thin` or `thick` or `length` or `none`\n* `medium`: Specifies a medium border. (usual default)\n* `thin`: Specifies a thin border\n* `thick`: Specifies a thick border\n* `length`: you to define the thickness of the border in [length](https://www.w3schools.com/cssref/css_units.asp) units.\n* `none`: No border width will be applied\n* `1px` is our default",
|
||||
"default": "1px"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderStyleTop": {
|
||||
"order": 18,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the top border style to be used by the line highlighter.\n\nSyntax: `none` or `hidden` or `dotted` or `dashed` or `solid` or `double` or `groove` or `ridge` or `inset` or `outset`\n* `none`: No border will be applied (usual default)\n* `hidden`: The same as `none`\n* `dotted`: Dotted border\n* `dashed`: Dashed border\n* `solid (our default)`: Solid border\n* `double`: Double border\n* `groove`: 3D grooved border, depends on the border-color value.\n* `ridge`: 3D ridged border, depends on the border-color value.\n* `inset`: 3D inset border, depends on the border-color value.\n* `outset`: 3D outset border, depends on the border-color value.",
|
||||
"default": "solid"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderStyleRight": {
|
||||
"order": 19,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the right border style to be used by the line highlighter.\n\nSyntax: `none` or `hidden` or `dotted` or `dashed` or `solid` or `double` or `groove` or `ridge` or `inset` or `outset`\n* `none`: No border will be applied (usual default)\n* `hidden`: The same as `none`\n* `dotted`: Dotted border\n* `dashed`: Dashed border\n* `solid (our default)`: Solid border\n* `double`: Double border\n* `groove`: 3D grooved border, depends on the border-color value.\n* `ridge`: 3D ridged border, depends on the border-color value.\n* `inset`: 3D inset border, depends on the border-color value.\n* `outset`: 3D outset border, depends on the border-color value.",
|
||||
"default": "solid"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderStyleBottom": {
|
||||
"order": 20,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the bottom border style to be used by the line highlighter.\n\nSyntax: `none` or `hidden` or `dotted` or `dashed` or `solid` or `double` or `groove` or `ridge` or `inset` or `outset`\n* `none`: No border will be applied (usual default)\n* `hidden`: The same as `none`\n* `dotted`: Dotted border\n* `dashed`: Dashed border\n* `solid (our default)`: Solid border\n* `double`: Double border\n* `groove`: 3D grooved border, depends on the border-color value.\n* `ridge`: 3D ridged border, depends on the border-color value.\n* `inset`: 3D inset border, depends on the border-color value.\n* `outset`: 3D outset border, depends on the border-color value.",
|
||||
"default": "solid"
|
||||
},
|
||||
"mind-reader.lineHighlighter.borderStyleLeft": {
|
||||
"order": 21,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the left border style to be used by the line highlighter.\n\nSyntax: `none` or `hidden` or `dotted` or `dashed` or `solid` or `double` or `groove` or `ridge` or `inset` or `outset`\n* `none`: No border will be applied (usual default)\n* `hidden`: The same as `none`\n* `dotted`: Dotted border\n* `dashed`: Dashed border\n* `solid (our default)`: Solid border\n* `double`: Double border\n* `groove`: 3D grooved border, depends on the border-color value.\n* `ridge`: 3D ridged border, depends on the border-color value.\n* `inset`: 3D inset border, depends on the border-color value.\n* `outset`: 3D outset border, depends on the border-color value.",
|
||||
"default": "solid"
|
||||
},
|
||||
"mind-reader.lineHighlighter.fontStyle": {
|
||||
"order": 22,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the font style to be used by the line highlighter.\n\nSyntax: `normal` or `italic` or `oblique` or `none`\n* `normal (our default)`: Displays a normal font style. This is default\n* `italic`: Displays an italic font style\n* `oblique`: Displays an oblique font style\n* `none`: No font style will be applied",
|
||||
"default": "normal"
|
||||
},
|
||||
"mind-reader.lineHighlighter.fontWeight": {
|
||||
"order": 23,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the font weight to be used by the line highlighter.\n\nSyntax: `normal` or `bold` or `bolder` or `lighter` or _number_ or `none`\n* `normal`: Normal Characters. (usual default)\n* `bold`: Thick Characters\n* `bolder (our default)`: Thicker Characters\n* `lighter`: Lighter Characters\n * _number_: From `thin` to `thick` characters: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, or `900`: `400` is the same as normal, and `700` is the same as bold.\n* `none`: No font weight will be applied",
|
||||
"default": "bolder"
|
||||
},
|
||||
"mind-reader.lineHighlighter.textDecoration": {
|
||||
"order": 24,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the text decoration to be used by the line highlighter.\n\nSyntax: `(text-decoration-line)` `(text-decoration-color)` `(text-decoration-style)` `(text-decoration-thickness)`\n* `text-decoration-line (required)`: Sets the kind of text decoration to use: `underline`, `overline`, `line-through`\n* `text-decoration-color`: Sets the color of the text decoration\n* `text-decoration-style`: Sets the style of the text decoration: `solid`, `wavy`, `dotted`, `dashed`, `double`\n* `text-decoration-thickness`: Sets the thickness of the decoration line\n* `none (our default)`: No text decorations will be applied\n\n`Examples`:\n1. underline blue wavy 5px\n2. line-through\n3. underline overline dotted red",
|
||||
"default": "none"
|
||||
},
|
||||
"mind-reader.lineHighlighter.textColor": {
|
||||
"order": 25,
|
||||
"type": "string",
|
||||
"markdownDescription": "Set the text color to be used by the line highlighter.\n\nSyntax: _color_ or `transparent`\n\nAvailable color formats include:\n* `HEX(A)`: for Hexadecimal Colors: `#RRGGBB` or `#RRGGBBAA` to add transparency\n* `RGB(A)`: for RGB Colors: `rgb(red, green, blue)` or `rgba(red, green, blue, alpha)`\n* `HSL(A)`: for HSL Colors: `hsl(hue, saturation, lightness)` or `hsla(hue, saturation, lightness, alpha)`\n* `Predefined Color Names`: 140 color names are predefined in the HTML and CSS color specification: `blue`, `red`, `coral`, `brown`, [etc...](https://www.w3schools.com/colors/colors_names.asp)\n* `None`: For no color to be applied: Sometimes VSCode will pull a color from your theme, other times it uses black\n* `#FFFFFF` is our default",
|
||||
"default": "#FFFFFF"
|
||||
}
|
||||
}
|
||||
}],
|
||||
"views": {
|
||||
"MindReader": [{
|
||||
"id": "accessActions",
|
||||
"name": "Access Actions",
|
||||
"icon": "media/dep.svg",
|
||||
@ -328,13 +576,11 @@
|
||||
]
|
||||
},
|
||||
"viewsContainers": {
|
||||
"activitybar": [
|
||||
{
|
||||
"activitybar": [{
|
||||
"id": "MindReader",
|
||||
"title": "MindReader Actions",
|
||||
"icon": "media/dep.svg"
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
|
65
setup-development/linux/install-linux.sh
Executable file
65
setup-development/linux/install-linux.sh
Executable file
@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
#* linux-install.sh: First-run setup script
|
||||
#* Ensures git is installed, clones the repo, and then runs
|
||||
|
||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||
ELEVATE='';if (( $UID !=0 )); then ELEVATE='sudo';fi
|
||||
|
||||
help () {
|
||||
echo "Usage: $0 [-d] [-g path/to/git/directory]"
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
gitdir=~/git
|
||||
|
||||
# Get option flags:
|
||||
dry=false
|
||||
while getopts ghd arg; do
|
||||
case $arg in
|
||||
g) gitdir="$OPTARG";;
|
||||
h) help;;
|
||||
d) dry=true;;
|
||||
esac
|
||||
done
|
||||
|
||||
function dryrun {
|
||||
if $dry; then
|
||||
echo "> $* [dry]";
|
||||
else
|
||||
echo "> $*"
|
||||
$@
|
||||
fi
|
||||
}
|
||||
|
||||
setupdir="Mind_Reader/setup-development/linux"
|
||||
repouri="https://github.com/We-Dont-Byte/Mind_Reader.git"
|
||||
|
||||
# Install git
|
||||
if which git; then
|
||||
echo "Git already installed."
|
||||
elif which pacman; then
|
||||
# using pacman
|
||||
dryrun $ELEVATE pacman -Sy git
|
||||
elif which apt; then
|
||||
# using apt
|
||||
dryrun $ELEVATE apt-get update && \
|
||||
dryrun $ELEVATE apt-get install git -y
|
||||
fi #? TODO: other package managers?
|
||||
|
||||
printf "\nCloning repository into $gitdir\n"
|
||||
dryrun mkdir "$gitdir"
|
||||
cd $gitdir && dryrun git clone "$repouri"
|
||||
|
||||
# TODO: remove this when merging!
|
||||
cd Mind_Reader
|
||||
dryrun git checkout johnBreaux
|
||||
# TODO: remove this when merging!
|
||||
|
||||
cd "$gitdir/$setupdir"
|
||||
bash ./upgrade-linux.sh $@
|
||||
|
||||
echo "Opening VS Code..."
|
||||
cd $gitdir/Mind_Reader
|
||||
code .
|
@ -0,0 +1,4 @@
|
||||
apt-transport-https
|
||||
build-essential
|
||||
python3
|
||||
wget
|
@ -0,0 +1,4 @@
|
||||
base-devel
|
||||
git
|
||||
wget
|
||||
python3
|
141
setup-development/linux/upgrade-linux.sh
Executable file
141
setup-development/linux/upgrade-linux.sh
Executable file
@ -0,0 +1,141 @@
|
||||
#!/bin/bash
|
||||
|
||||
#* linux-update.sh: Install and update dependencies of Mind Reader, on linux.
|
||||
#* Heads-up, this expects to be run from Mind_Reader/setup-development/linux.
|
||||
|
||||
# If run with bash -vx, print useful information instead of just a + sign
|
||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||
# If run as root, it could be because sudo isn't installed (some people disagree with sudo, especially on Arch)
|
||||
ELEVATE='';if (( $UID !=0 )); then ELEVATE='sudo';fi
|
||||
|
||||
# Get option flags:
|
||||
dry=false
|
||||
while getopts d arg; do
|
||||
case $arg in
|
||||
d) dry=true;;
|
||||
esac
|
||||
done
|
||||
|
||||
function dryrun {
|
||||
if $dry; then
|
||||
echo "> $* [dry]";
|
||||
else
|
||||
echo "> $*"
|
||||
$@
|
||||
fi
|
||||
}
|
||||
|
||||
# Get whether the user is running in Windows Subsystem for Linux
|
||||
function getwsl {
|
||||
grep "[Mm]icrosoft" /proc/version > /dev/null
|
||||
return $?
|
||||
}
|
||||
|
||||
# Get the user's default login shell
|
||||
function getsh {
|
||||
#* This code was created by user [Todd A. Jacobs](https://stackoverflow.com/users/1301972/todd-a-jacobs) on [StackOverflow](https://stackoverflow.com/a/11059152) and is used in accordance with Creative Commons CC BY-SA 3.0
|
||||
getent passwd $LOGNAME | cut -d: -f7
|
||||
}
|
||||
|
||||
# Install NVM (this is gross, but the recommended way to install nvm)
|
||||
function installnvm {
|
||||
# nvm's install script tries to be smart, so we have to work around its supposed cleverness
|
||||
usershell=`getsh`
|
||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | dryrun "$usershell"
|
||||
# Reload profile
|
||||
case $usershell in
|
||||
*/bash) dryrun . ~/.bashrc ~/.bashprofile;;
|
||||
*/zsh) dryrun . ~/.zshrc;;
|
||||
*) "Your shell, $usershell, is currently unsupported by nvm. It's up to you to set up your development environment."; exit;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Set these variables if you need to install for a different architecture
|
||||
# Valid architectures are "x64", "arm64", "armhf"
|
||||
arch=""
|
||||
case `uname -i` in
|
||||
"x86_64") arch="x64";;
|
||||
"armv[6-8]*") arch="armhf";;
|
||||
"aarch64") arch="arm64";;
|
||||
*) echo "Architecture '$(uname -i)' unknown. Assuming x86_64..."
|
||||
arch="x64";;
|
||||
esac
|
||||
|
||||
if which pacman; then
|
||||
# Install dependencies with pacman
|
||||
printf "Installing dependencies with pacman...\n"
|
||||
cat ./package-managers/pacman.dependencies | dryrun $ELEVATE pacman -S --needed -
|
||||
# If not in Windows Subsystem for Linux, install vscode
|
||||
[[ !(getwsl) ]] && dryrun $ELEVATE pacman -S --needed code
|
||||
# Install Node Version Manager
|
||||
installnvm
|
||||
|
||||
elif which apt-get; then
|
||||
# Install dependencies using apt-get
|
||||
printf "Installing dependencies with apt...\n"
|
||||
dryrun xargs -a ./package-managers/apt.dependencies $ELEVATE apt-get install -y
|
||||
# Check if vscode exists, if not, install it.
|
||||
# Microsoft doesn't put it in any Ubuntu repos, you have to get it straight from them.
|
||||
# This does have the side effect, however, of installing the official repository
|
||||
# Don't attempt to install vscode if running in WSL; it can cause problems.
|
||||
if !(which code) && !(getwsl); then
|
||||
#* Install VSCode
|
||||
vscodepackagename="code_amd64.deb"
|
||||
dryrun wget "https://code.visualstudio.com/sha/download?build=stable&os=linux-deb-$arch" -O ./code.deb
|
||||
dryrun $ELEVATE apt install ./code.deb
|
||||
dryrun rm ./code.deb
|
||||
fi
|
||||
# Install Node Version Manager (nvm)
|
||||
installnvm
|
||||
|
||||
fi
|
||||
|
||||
cdir=$(pwd)
|
||||
# Go back to source tree root
|
||||
cd ../..
|
||||
|
||||
# Check the VSCode version
|
||||
nodeversion="node"
|
||||
electronversion=""
|
||||
#* Note:
|
||||
#* When adding support for new VSCode versions, update this case
|
||||
#* By the time you're working on this project, things are likely going to differ!
|
||||
case `code --version` in
|
||||
#* Each version of VSCode has a corresponding Electron version and Node version
|
||||
#* These are used when configuring nvm
|
||||
1.66.*) electronversion="17.2.0"; nodeversion="16.13.0";;
|
||||
1.67.*) electronversion="17.4.1"; nodeversion="16.13.0";;
|
||||
*) nodeversion="--lts";;
|
||||
esac
|
||||
|
||||
# Install NodeJS and npm
|
||||
printf "\nInstalling node $nodeversion\n"
|
||||
dryrun nvm install "$nodeversion"
|
||||
dryrun nvm use "$nodeversion"
|
||||
|
||||
# Use npm to install electron-rebuild and yo
|
||||
printf "Installing electron-rebuild, yo, and generator-code\n"
|
||||
dryrun npm install electron-rebuild yo generator-code
|
||||
|
||||
# use npm to acquire dependencies for Mind-Reader
|
||||
printf "\nAcquiring dependencies...\n"
|
||||
dryrun npm install
|
||||
|
||||
# automatically update vulnerable packages, if possible
|
||||
printf "\nUpdating vulnerable packages, if possible...\n"
|
||||
dryrun npm audit fix
|
||||
|
||||
# Use electron-rebuild to rebuild electron
|
||||
if [[ "$electronversion" != "" ]]; then
|
||||
printf "\nRebuilding electron with version $electronversion...\n"
|
||||
dryrun electron-rebuild --version $electronversion
|
||||
else
|
||||
printf "\n%s\n%s\n%s\n%s\n" \
|
||||
"Open Visual Studio Code, select the 'Help' tab in the toolbar, and go to 'About'." \
|
||||
"Find the line that says 'Electron: [electron version]'" \
|
||||
"Run the command below, filling in the Electron version with the one from that menu:" \
|
||||
"electron-rebuild --version [electron version]"
|
||||
fi
|
||||
|
||||
cd $cdir
|
||||
echo "Done!"
|
179
setup-development/windows/install-windows.ps1
Normal file
179
setup-development/windows/install-windows.ps1
Normal file
@ -0,0 +1,179 @@
|
||||
<#
|
||||
.synopsis
|
||||
Dependency installer for Mind Reader on Windows.
|
||||
This sets up a development environment from a BARE windows install.
|
||||
|
||||
.description
|
||||
Install Git for Windows, clone the Mind Reader repository, and install all dependencies.
|
||||
|
||||
The script uses winget (A.K.A. "App Installer") to download and install the latest versions of each dependency, defined in winget/dependencies.json
|
||||
|
||||
Winget comes preinstalled on Windows 11 (21H2)/10 (21H1) or newer, and can be installed on Windows 10 1704+ through the Windows Store.
|
||||
If you download Microsoft's developer VM, you have it!
|
||||
As WinGet is built into Windows, it sidesteps any annoying third-party package managers, and is the lowest common denominator for package installation.
|
||||
|
||||
.link
|
||||
https://github.com/We-Dont-Byte/Mind_Reader/
|
||||
|
||||
.parameter GitDir
|
||||
Path to clone the git repo into (Default: $HOME/git/)
|
||||
|
||||
.parameter AllowAdministrator
|
||||
Force-allow running this script as Administrator (not recommended, despite the frequent UAC prompts!)
|
||||
|
||||
.parameter NoPrompt
|
||||
Disable all prompts for user input, and all waiting. (not recommended when combined with AllowAdministrator!)
|
||||
|
||||
.parameter ForceInstall
|
||||
Force installation/upgrade of all modules, even if already present on the system.
|
||||
|
||||
.parameter DryRun
|
||||
Perform a "dry run" of the script, changing directories and running commands, but without modifying anything.
|
||||
|
||||
.example
|
||||
./install-windows.ps1
|
||||
Perform a default upgrade of all Mind Reader dependencies
|
||||
|
||||
.example
|
||||
./install-windows.ps1 -DryRun
|
||||
Perform a dry run of the upgrade process, so you can evaluate what commands will be run
|
||||
|
||||
.example
|
||||
./install-windows.ps1 -NoPrompt
|
||||
Don't prompt for user input when upgrading
|
||||
|
||||
.example
|
||||
./install-windows.ps1 AllowAdministrator
|
||||
Allow script to run as Administrator
|
||||
#>
|
||||
|
||||
param (
|
||||
[string]$GitDir = "$HOME/git/", # Path to clone the git repo into
|
||||
[switch]$h, [switch]$Help, # Get help
|
||||
[switch]$AllowAdministrator, # Force allow installation as administrator
|
||||
[switch]$NoPrompt, # Disable the 3-second wait and press-any-key prompt
|
||||
[switch]$ForceInstall, # Always try to install
|
||||
[switch]$DryRun # Run script without installing
|
||||
)
|
||||
|
||||
$RepoURI = "https://github.com/We-Dont-Byte/Mind_Reader.git"
|
||||
$RepoPath = "$GitDir\Mind_Reader"
|
||||
$SetupPath = "$RepoPath\setup-development\windows"
|
||||
|
||||
if ($h -or $Help) {
|
||||
Get-Help ./install-windows.ps1
|
||||
exit
|
||||
}
|
||||
|
||||
# .description
|
||||
# Get-CommandAvailable: Checks whether a given command is available.
|
||||
# If command is available, returns $false
|
||||
function Get-CommandAvailable {
|
||||
param ($command)
|
||||
# Use a wildcard here so the command doesn't throw an exception we'd have to trycatch
|
||||
# It's not a filthy hack if it's elegant!
|
||||
RETURN (Get-Command -Name $command*)
|
||||
}
|
||||
|
||||
#.description
|
||||
# Invoke-DryRun a powershell statement
|
||||
function Invoke-DryRun {
|
||||
param ([string] $command)
|
||||
$prompt = "> "
|
||||
if ($DryRun) {
|
||||
Write-Host "$prompt$command [dry]" -ForegroundColor darkgray
|
||||
}
|
||||
else {
|
||||
Write-Host "$prompt$command" -ForegroundColor white
|
||||
Invoke-Expression $command
|
||||
}
|
||||
}
|
||||
|
||||
#.description
|
||||
# Reset-Path: Reload the Path environment variable
|
||||
function Reset-Path {
|
||||
Write-Output "Reloading Path..."
|
||||
#* This code was created by user [mpen](https://stackoverflow.com/users/65387/mpen) on [StackOverflow](https://stackoverflow.com/a/31845512) and is used in accordance with Creative Commons CC BY-SA 3.0
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
}
|
||||
|
||||
|
||||
# Check if Winget is available
|
||||
if ( -not (Get-CommandAvailable winget) ) {
|
||||
Write-Warning "It looks like winget isn't available.`n"
|
||||
Write-Host "Update 'App Installer' through the Microsoft Store, or grab the '.msixbundle' from the winget-cli repository:"
|
||||
Write-Host "( https://github.com/microsoft/winget-cli/releases/latest )`n" -ForegroundColor White
|
||||
exit
|
||||
}
|
||||
|
||||
# Check if the user ran the script with administrator privileges.
|
||||
# Warn them.
|
||||
if ( ([Security.Principal.WindowsIdentity]::GetCurrent().Groups -contains 'S-1-5-32-544') ) {
|
||||
# If an administrator requests installation as administator,
|
||||
# for example, to keep UAC prompts to a minimum, allow it.
|
||||
if ($AllowAdministrator) {
|
||||
Write-Warning "Script was run as Administrator. Exit now if you didn't mean to do this!"
|
||||
# If you pass NoPrompt as an arg, you're very aware of the damage this script could do to your build env, and you just don't care
|
||||
# The true chad of sysadmins.
|
||||
if (!$NoPrompt) {
|
||||
for ( $i = 3; $i -gt 0; $i--) {
|
||||
Write-Host "Press Ctrl+C to exit. Continuing in $i...`r" -NoNewLine
|
||||
Start-Sleep 1
|
||||
}
|
||||
Write-Host "Press any key to continue... "
|
||||
[void][Console]::ReadKey(1) # Equivalent to Command Prompt's `pause` command
|
||||
}
|
||||
} else {
|
||||
# Throw a fatal error if the user tries to run as administrator.
|
||||
Throw "Script must be run as a normal user."
|
||||
}
|
||||
}
|
||||
|
||||
# Install Git
|
||||
if ( -not (Get-CommandAvailable git) ) {
|
||||
Write-Host "`nInstalling Git with winget..."
|
||||
Invoke-DryRun 'winget install --id Git.Git'
|
||||
Reset-Path
|
||||
if ( -not (Get-CommandAvailable git)) {
|
||||
Throw "Git failed to install. Aborting."
|
||||
}
|
||||
} else {
|
||||
Write-Host "Git already installed." -ForegroundColor green
|
||||
}
|
||||
|
||||
# Create git directory in GitDir
|
||||
if ( -not (Test-Path "$GitDir") ) {
|
||||
Invoke-DryRun "mkdir '$GitDir'"
|
||||
}
|
||||
|
||||
# Clone the repository in GitDir
|
||||
$dir = $pwd
|
||||
Set-Location $GitDir
|
||||
Invoke-DryRun "git clone '$RepoURI'"
|
||||
|
||||
# TODO: Remove this when merging
|
||||
Set-Location Mind_reader
|
||||
Invoke-DryRun "git checkout johnBreaux"
|
||||
Set-Location ..
|
||||
# TODO: Remove this when merging
|
||||
|
||||
# Run the install script
|
||||
if ( -not (Test-Path "$SetupPath")) {
|
||||
Throw "Repository contains no subdirectory '$SetupPath'."
|
||||
}
|
||||
Set-Location $SetupPath
|
||||
# Run upgrade-windows to install the rest of the dependency chain.
|
||||
$upgradeArgs = if ($AllowAdministrator) {" -AllowAdministrator"} else {""}
|
||||
$upgradeArgs += if ($DryRun) {" -DryRun"} else {""}
|
||||
PowerShell ("./upgrade-windows.ps1 -Install -NoPrompt" + $upgradeArgs)
|
||||
Reset-Path
|
||||
|
||||
# Open VSCode in the repository location
|
||||
Write-Host "`nOpening Visual Studio Code"
|
||||
Set-Location $RepoPath
|
||||
Invoke-DryRun "code ."
|
||||
|
||||
Set-Location $dir
|
||||
if ( -not $NoPrompt ) {
|
||||
Write-Host "`nPress any key to exit."; [void][Console]::ReadKey(1)
|
||||
}
|
214
setup-development/windows/upgrade-windows.ps1
Normal file
214
setup-development/windows/upgrade-windows.ps1
Normal file
@ -0,0 +1,214 @@
|
||||
<#
|
||||
.synopsis
|
||||
Dependency updater for Mind Reader on Windows.
|
||||
This script expects to be run from Mind_Reader/setup-development
|
||||
|
||||
.description
|
||||
Updates dependencies (NodeJS, Python, etc.), VSCode, NVDA
|
||||
|
||||
The script uses winget (A.K.A. "App Installer") to download and install the latest versions of each dependency, defined in winget/dependencies.json
|
||||
|
||||
Winget comes preinstalled on Windows 11 (21H2)/10 (21H1) or newer, and can be installed on Windows 10 1704+ through the Windows Store.
|
||||
If you download Microsoft's developer VM, you have it!
|
||||
As WinGet is built into Windows, it sidesteps any annoying third-party package managers, and is the lowest common denominator for package installation.
|
||||
|
||||
.link
|
||||
https://github.com/We-Dont-Byte/Mind_Reader/
|
||||
|
||||
.parameter GitDir
|
||||
Path to clone the git repo into (Default: $HOME/git/)
|
||||
|
||||
.parameter AllowAdministrator
|
||||
Force-allow running this script as Administrator (not recommended, despite the frequent UAC prompts!)
|
||||
|
||||
.parameter NoPrompt
|
||||
Disable all prompts for user input, and all waiting. (not recommended when combined with AllowAdministrator!)
|
||||
|
||||
.parameter Install
|
||||
Force installation/upgrade of all modules, even if already present on the system.
|
||||
|
||||
.parameter DryRun
|
||||
Perform a "dry run" of the script, changing directories and running commands, but without modifying anything.
|
||||
|
||||
.example
|
||||
./upgrade-windows.ps1
|
||||
Perform a default upgrade of all Mind Reader dependencies
|
||||
|
||||
.example
|
||||
./upgrade-windows.ps1 -DryRun
|
||||
Perform a dry run of the upgrade process, so you can evaluate what commands will be run
|
||||
|
||||
.example
|
||||
./upgrade-windows.ps1 -NoPrompt
|
||||
Don't prompt for user input when upgrading
|
||||
|
||||
.example
|
||||
./upgrade-windows.ps1 -AllowAdministrator
|
||||
Allow script to be run as Administrator
|
||||
#>
|
||||
|
||||
param (
|
||||
[switch]$AllowAdministrator, # Force allow installation as administrator
|
||||
[switch]$NoPrompt, # Disable the 3-second wait and press-any-key prompt
|
||||
[switch]$Install, # Perform all installations, even when commands are present
|
||||
[switch]$DryRun, # Run script without installing
|
||||
[switch]$NoWinget # Don't update dependdencies with winget
|
||||
)
|
||||
|
||||
# .description
|
||||
# Get-CommandAvailable: Checks whether a given command is available.
|
||||
# If command is available, returns $false
|
||||
function Get-CommandAvailable {
|
||||
param ($command)
|
||||
# Use a wildcard here so the command doesn't throw an exception we'd have to trycatch
|
||||
# It's not a filthy hack if it's elegant!
|
||||
RETURN (Get-Command -Name $command*)
|
||||
}
|
||||
|
||||
#.description
|
||||
# Invoke-Dryrun a powershell statement
|
||||
function Invoke-Dryrun {
|
||||
param ([string] $command)
|
||||
$prompt = "> "
|
||||
if ($DryRun) {
|
||||
Write-Host "$prompt$command [dry]" -ForegroundColor darkgray
|
||||
}
|
||||
else {
|
||||
Write-Host "$prompt$command" -ForegroundColor white
|
||||
Invoke-Expression $command
|
||||
}
|
||||
}
|
||||
|
||||
#.description
|
||||
# Reset-Path: Reload the Path environment variable
|
||||
function Reset-Path {
|
||||
Write-Output "Reloading Path..."
|
||||
#* This code was created by user [mpen](https://stackoverflow.com/users/65387/mpen) on [StackOverflow](https://stackoverflow.com/a/31845512) and is used in accordance with Creative Commons CC BY-SA 3.0
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
}
|
||||
|
||||
|
||||
# Check if Winget is available
|
||||
if ( -not (Get-CommandAvailable winget) ) {
|
||||
Write-Warning "It looks like winget isn't available.`n"
|
||||
Write-Host "Update 'App Installer' through the Microsoft Store, or grab the '.msixbundle' from the winget-cli repository:"
|
||||
Write-Host "( https://github.com/microsoft/winget-cli/releases/latest )`n" -ForegroundColor White
|
||||
exit
|
||||
}
|
||||
|
||||
# Check if the user ran the script with administrator privileges.
|
||||
# Warn them.
|
||||
if ( ([Security.Principal.WindowsIdentity]::GetCurrent().Groups -contains 'S-1-5-32-544') ) {
|
||||
# If an administrator requests installation as administator,
|
||||
# for example, to keep UAC prompts to a minimum, allow it.
|
||||
if ($AllowAdministrator) {
|
||||
# If you pass -AllowAdministrator -NoPrompt as an arg, you're very aware of the damage this script could do to your build env, and you just don't care
|
||||
# The true chad of sysadmins.
|
||||
if (!$NoPrompt) {
|
||||
Write-Warning "Script was run as Administrator. Exit now if you didn't mean to do this!"
|
||||
for ( $i = 3; $i -gt 0; $i--) {
|
||||
Write-Host "Press Ctrl+C to exit. Continuing in $i...`r" -NoNewLine
|
||||
Start-Sleep 1
|
||||
}
|
||||
|
||||
Write-Host "Press any key to continue... "
|
||||
[void][Console]::ReadKey(1) # Equivalent to Command Prompt's `pause` command
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Throw a fatal errorOccurred if the user tries to run as administrator.
|
||||
Throw "Script must be run as a normal user."
|
||||
}
|
||||
}
|
||||
|
||||
# Import the packages from dependencies.json (autogenerated file, do not edit!)
|
||||
if ( -not $NoWinget) {
|
||||
Write-Host "`nInstalling packages with winget..."
|
||||
Invoke-Dryrun 'winget install Microsoft.VisualStudio.2022.BuildTools --override "--wait --quiet --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"'
|
||||
Invoke-Dryrun "winget import winget/dependencies.json"
|
||||
# Reload the PATH, so we can use some of those sweet new commands we just installed
|
||||
Reset-Path
|
||||
}
|
||||
|
||||
# Check whether everything is available now:
|
||||
$errorOccurred = 0
|
||||
if ( -not (Get-CommandAvailable code) ) {
|
||||
$errorOccurred += 1; Write-Host -ForegroundColor red "Visual Studio Code not available"
|
||||
}
|
||||
if ( -not (Get-CommandAvailable node) ) {
|
||||
$errorOccurred += 2; Write-Host -ForegroundColor red "NodeJS not available"
|
||||
}
|
||||
if ( -not (Get-CommandAvailable npm ) ) {
|
||||
$errorOccurred += 4; Write-Host -ForegroundColor red "Node Package Manager not available";
|
||||
}
|
||||
if ( $errorOccurred ) { exit }
|
||||
|
||||
# .description
|
||||
# EnsureNodePackageInstalled:
|
||||
# Checks for the presence of a cmdlet with a given name
|
||||
# If it's not found, attempt to install it using npm
|
||||
# If it's still not found, abort (this may not be good behavior?)
|
||||
function EnsureNodePackageInstalled {
|
||||
param (
|
||||
[string[]]$command
|
||||
)
|
||||
if ( ($Install) -or -not (Get-CommandAvailable $command[0]) ) {
|
||||
Write-Host "`nInstalling $($command[0])..."
|
||||
Invoke-Dryrun "npm install -g $([string]$command)"
|
||||
Reset-Path
|
||||
if ( -not (Get-CommandAvailable $command[0])) {
|
||||
Throw "$command failed to install. Aborting."
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "`n$($command[0]) already installed." -ForegroundColor green
|
||||
}
|
||||
}
|
||||
|
||||
# Check if electron-rebuild is installed, if not, install it
|
||||
EnsureNodePackageInstalled electron-rebuild
|
||||
|
||||
# These are useful (but not necessary) packages to have installed when working on new VSCode extensions
|
||||
EnsureNodePackageInstalled yo, generator-code
|
||||
|
||||
# We're about to do some path traversal, so save the current directory
|
||||
$prev_directory = $pwd
|
||||
|
||||
# install NodeJS dependencies for this extension
|
||||
Write-Host "`nInstalling NodeJS Dependencies..."
|
||||
Set-Location ..\..
|
||||
Invoke-Dryrun "npm install"
|
||||
|
||||
# Run npm audit fix to upgrade vulnerable dependencies, except breaking changes.
|
||||
Invoke-Dryrun "npm audit fix"
|
||||
|
||||
# if we're on a known VSCode version, go ahead and run electron-rebuild
|
||||
switch -Regex (code --version) {
|
||||
#?: Do we update this in the future, or stop maintaining it and remove this entire switch block?
|
||||
"1\.67\.\d+" { $electronversion = "17.4.1"; break } # April 2022 update
|
||||
"1\.66\.\d+" { $electronversion = "17.2.0"; break } # March 2022 update
|
||||
default { $electronversion = $false } # Unknown update
|
||||
}
|
||||
|
||||
if ( $electronversion ) {
|
||||
Write-Host "`nRebuilding Electron for your version of VSCode..."
|
||||
Invoke-Dryrun "electron-rebuild --version='$electronversion'"
|
||||
Write-Host "Done!" -ForegroundColor green
|
||||
}
|
||||
else {
|
||||
Write-Host "`nOpen Visual Studio Code, select the `"Help`" tab in the Toolbar, and go to `"About`".`nYou should see a page that looks like the following:" -ForegroundColor darkcyan
|
||||
|
||||
Write-Host " `(i`) Visual Studio Code`n`n Version: 1.66.2 `(user setup`)`n Commit: [Commit ID]`n Date: 2022-04-11T07:46:01.075Z`n Electron: 17.2.0`n [ ... ]" -ForegroundColor White
|
||||
|
||||
Write-Host "Note the Electron version `(17.2.0 in the above example`)." -ForegroundColor darkcyan
|
||||
|
||||
Write-Host "Run the command " -NoNewLine
|
||||
Write-Host "electron-rebuild --version ELECTRON_VERSION" -NoNewLine -ForegroundColor green
|
||||
Write-Host " in Mind Reader`'s root folder.`n"
|
||||
}
|
||||
|
||||
# Return from whence we came
|
||||
Set-Location $prev_directory
|
||||
if ( -not $NoPrompt ) {
|
||||
Write-Host "`nPress any key to exit."; [void][Console]::ReadKey(1)
|
||||
}
|
29
setup-development/windows/winget/dependencies.json
Normal file
29
setup-development/windows/winget/dependencies.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://aka.ms/winget-packages.schema.2.0.json",
|
||||
"CreationDate": "2022-04-23T21:13:03.702-00:00",
|
||||
"Sources": [
|
||||
{
|
||||
"Packages": [
|
||||
{
|
||||
"PackageIdentifier": "Python.Python.3"
|
||||
},
|
||||
{
|
||||
"PackageIdentifier": "Git.Git"
|
||||
},
|
||||
{
|
||||
"PackageIdentifier": "OpenJS.NodeJS.LTS"
|
||||
},
|
||||
{
|
||||
"PackageIdentifier": "Microsoft.VisualStudioCode"
|
||||
}
|
||||
],
|
||||
"SourceDetails": {
|
||||
"Argument": "https://winget.azureedge.net/cache",
|
||||
"Identifier": "Microsoft.Winget.Source_8wekyb3d8bbwe",
|
||||
"Name": "winget",
|
||||
"Type": "Microsoft.PreIndexed.Package"
|
||||
}
|
||||
}
|
||||
],
|
||||
"WinGetVersion": "1.2.10271"
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import HubManager from '../hubManager';
|
||||
//import EV3Manager from '../ev3Manager';
|
||||
|
||||
import { CommandEntry } from './commandEntry';
|
||||
|
||||
@ -33,12 +34,23 @@ export const hubCommands: CommandEntry[] = [
|
||||
{
|
||||
name: 'mind-reader.deleteProgram',
|
||||
callback: deleteProgram
|
||||
},
|
||||
}/*,
|
||||
{
|
||||
name: 'mind-reader.ev3.test',
|
||||
callback: ev3test
|
||||
}*/
|
||||
];
|
||||
|
||||
// Current connected hub
|
||||
let hub: HubManager | null = null;
|
||||
/*
|
||||
let ev3: EV3Manager | null = null;
|
||||
|
||||
async function ev3test(): Promise<void> {
|
||||
ev3 = await EV3Manager.activate();
|
||||
ev3.test();
|
||||
}
|
||||
*/
|
||||
async function connectHub(): Promise<void> {
|
||||
if (hub && hub.isOpen()) {
|
||||
vscode.window.showWarningMessage('LEGO Hub is already connected, reconnecting...');
|
||||
@ -53,7 +65,7 @@ async function connectHub(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
let portPath: string | undefined = vscode.workspace.getConfiguration('mindReader.connection').get('portPath');
|
||||
let portPath: string | undefined = vscode.workspace.getConfiguration('mind-reader.connection').get('portPath');
|
||||
|
||||
if (!portPath) {
|
||||
let slots: vscode.QuickPickItem[] = [];
|
||||
|
@ -1,24 +1,19 @@
|
||||
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[] = [
|
||||
{
|
||||
name: 'mind-reader.openWebview',
|
||||
callback: openWebview,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'mind-reader.openKeyBindWin',
|
||||
callback: () => openKeyBindWin('Windows')
|
||||
},
|
||||
{
|
||||
name: 'mind-reader.openKeyBindMac',
|
||||
callback: () => openKeyBindWin('Mac'),
|
||||
name: "mind-reader.openKeybinds",
|
||||
callback: () => vscode.commands.executeCommand("workbench.action.openGlobalKeybindings", "mind-reader"),
|
||||
},
|
||||
|
||||
//Navigation Keys......
|
||||
// TODO: Why is this here? Extensions can rebind existing keybinds.
|
||||
{
|
||||
name: 'mind-reader.showAllSymbols',
|
||||
callback: () => vscode.commands.executeCommand('workbench.action.showAllSymbols'),
|
||||
@ -82,35 +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>`;
|
||||
}
|
||||
|
||||
function openKeyBindWin(os: 'Mac' | 'Windows'): void {
|
||||
//vscode.commands.executeCommand('workbench.action.zoomOut');
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'mindReader', // Identifies the type of the webview. Used internally
|
||||
'MR Key Bindings', // 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.
|
||||
|
||||
if (os === 'Windows') {
|
||||
panel.webview.html = getWebviewContent('media/html/winkeys.html');
|
||||
} else if (os === 'Mac') {
|
||||
panel.webview.html = getWebviewContent('media/html/mackeys.html');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,74 +1,275 @@
|
||||
import * as vscode from 'vscode';
|
||||
import * as pl from '../pylex';
|
||||
|
||||
"use strict";
|
||||
import pl = require("../pylex");
|
||||
import { CommandEntry } from './commandEntry';
|
||||
import { Position, Selection, TextEditor, TextLine, window, workspace } from "vscode";
|
||||
|
||||
export const textCommands: CommandEntry[] = [
|
||||
{
|
||||
name: 'mind-reader.getLineNumber',
|
||||
callback: getLineNumber,
|
||||
},
|
||||
{
|
||||
name: 'mind-reader.getIndent',
|
||||
callback: getIndent,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'mind-reader.runLineContext',
|
||||
name: 'mind-reader.getLeadingSpaces',
|
||||
callback: getLeadingSpaces,
|
||||
},
|
||||
{
|
||||
name: 'mind-reader.selectLeadingWhitespace',
|
||||
callback: selectLeadingWhitespace
|
||||
},
|
||||
{
|
||||
name: 'mind-reader.getNumberOfSelectedLines',
|
||||
callback: getNumberOfSelectedLines,
|
||||
},
|
||||
{
|
||||
name: 'mind-reader.getLineScope',
|
||||
callback: runLineContext,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'mind-reader.runCursorContext',
|
||||
name: 'mind-reader.getWordsUnderCursor',
|
||||
callback: runCursorContext
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
function getIndent(): void {
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
if(editor)
|
||||
{
|
||||
let lineNum = editor.selection.active.line + 1;
|
||||
let textLine = editor.document.lineAt(lineNum - 1);
|
||||
if(textLine.isEmptyOrWhitespace)
|
||||
{
|
||||
vscode.window.showInformationMessage("Line number " + lineNum.toString() + " Is Empty");
|
||||
/** 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 fetchNumberOfLeadingSpaces(editor: TextEditor | undefined): number {
|
||||
let numSpaces: number = 0;
|
||||
|
||||
|
||||
if (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);
|
||||
|
||||
/* If true, calculate by arithmetic otherwise get index */
|
||||
numSpaces = (calculateLeadingSpaces)
|
||||
? pl.Lexer.getLeadingSpacesByArithmetic(line)
|
||||
: pl.Lexer.getLeadingSpacesByIndex(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
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`);
|
||||
}
|
||||
else {
|
||||
window.showErrorMessage('No document currently active');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
window.showInformationMessage(`Line ${lineNum.toString()}`);
|
||||
}
|
||||
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
|
||||
let tabFmt = {
|
||||
size: editor.options.tabSize as number,
|
||||
const tabFmt: pl.TabInfo = {
|
||||
size: typeof editor.options.tabSize === 'number'? editor.options.tabSize: 4,
|
||||
hard: !editor.options.insertSpaces
|
||||
};
|
||||
let i = pl.Lexer.getIndent(textLine.text, tabFmt);
|
||||
vscode.window.showInformationMessage("Line Number " + lineNum.toString() + " Indentation " + i.toString());
|
||||
const i: number = pl.Lexer.getIndent(line.text, tabFmt);
|
||||
|
||||
(i !== 1)
|
||||
? window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indents`)
|
||||
: window.showInformationMessage(`Line ${lineNum.toString()}: ${i.toString()} indent`);
|
||||
}
|
||||
}
|
||||
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
|
||||
*/
|
||||
function getLeadingSpaces(): void {
|
||||
const editor: TextEditor | undefined = window.activeTextEditor;
|
||||
|
||||
if (editor) {
|
||||
const lineNum : number = fetchLineNumber(editor);
|
||||
const line : TextLine | undefined = fetchLine(editor);
|
||||
|
||||
if (line.isEmptyOrWhitespace) {
|
||||
window.showInformationMessage(`Line ${lineNum.toString()} is empty`);
|
||||
}
|
||||
else {
|
||||
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)
|
||||
? window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} spaces`)
|
||||
: window.showInformationMessage(`Line ${lineNum.toString()}: ${numSpaces.toString()} space`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
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`);
|
||||
|
||||
// Move the cursor to the new selection
|
||||
window.showTextDocument(editor.document);
|
||||
}
|
||||
else {
|
||||
window.showErrorMessage(`Line ${lineNum.toString()}: No leading spaces to select!`); // No whitespace to select
|
||||
}
|
||||
}
|
||||
else {
|
||||
window.showErrorMessage('No document currently active'); // No active document
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function runLineContext(): void {
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
const editor: TextEditor | undefined = window.activeTextEditor;
|
||||
|
||||
if (editor) {
|
||||
// current text and line number
|
||||
let editorText = editor.document.getText();
|
||||
let line = editor.selection.active.line;
|
||||
|
||||
const editorText: string = editor.document.getText();
|
||||
const line : number = editor.selection.active.line;
|
||||
// get tab info settings
|
||||
let size = parseInt(editor.options.tabSize as string);
|
||||
let hard = !editor.options.insertSpaces;
|
||||
|
||||
const size : number = typeof editor.options.tabSize === 'number'? editor.options.tabSize: 4;
|
||||
const hard : boolean = !editor.options.insertSpaces;
|
||||
// initialize parser
|
||||
let parser = new pl.Parser(editorText, {size, hard});
|
||||
const parser : pl.Parser = new pl.Parser(editorText, {
|
||||
size,
|
||||
hard
|
||||
});
|
||||
|
||||
parser.parse();
|
||||
|
||||
let context = parser.context(line);
|
||||
|
||||
const context: pl.LexNode[] = parser.context(line);
|
||||
// build text
|
||||
let contentString = createContextString(context, line);
|
||||
vscode.window.showInformationMessage(contentString);
|
||||
} else {
|
||||
vscode.window.showErrorMessage('No document currently active');
|
||||
const contentString: string = createContextString(context, line);
|
||||
|
||||
window.showInformationMessage(contentString);
|
||||
}
|
||||
else {
|
||||
window.showErrorMessage('No document currently active');
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,92 +278,111 @@ function createContextString(context: pl.LexNode[], line: number): string {
|
||||
throw new Error('Cannot create context string for empty context');
|
||||
}
|
||||
|
||||
let contextString = 'Line ' + (line+1); // 1 based
|
||||
let contextString: string = `Line ${line + 1}`; // 1 based
|
||||
// Print the current line
|
||||
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;
|
||||
let tokenTypeString: string = `${context[0].token.type.toString()}`;
|
||||
contextString += `: ${tokenTypeString !== pl.PylexSymbol.STATEMENT?tokenTypeString:""
|
||||
} ${context[0].token.attr.toString()}`;
|
||||
}
|
||||
|
||||
if (node.token!.type !== pl.PylexSymbol.EMPTY &&
|
||||
node.token!.type !== pl.PylexSymbol.INDENT) {
|
||||
contextString += ' inside ' + node.token!.type.toString();
|
||||
if (node.token!.attr) {
|
||||
contextString += ' ' + node.token!.attr.toString();
|
||||
for (let i: number = 1; i < context.length; i++) {
|
||||
const node: pl.LexNode = context[i];
|
||||
const inside: string = "inside";
|
||||
// Node contains information relevant to the current line
|
||||
if (node.token && node.token.type !== pl.PylexSymbol.EMPTY &&
|
||||
node.token.type !== pl.PylexSymbol.STATEMENT) {
|
||||
contextString += ` ${inside} ${node.token.type.toString()}`;
|
||||
if (node.token.attr) {
|
||||
contextString += ` ${node.token.attr.toString()}`;
|
||||
}
|
||||
}
|
||||
// Node is the document root
|
||||
if (node.label === 'root') {
|
||||
// Append the name (relative path) of the document in the workspace
|
||||
if (window.activeTextEditor?.document.uri) {
|
||||
contextString += ` ${inside} ${workspace.asRelativePath(window.activeTextEditor?.document.uri)}`;
|
||||
} else {
|
||||
contextString += ` ${inside} the Document`;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
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 `#mind-reader.reader.contextWindow`
|
||||
*/
|
||||
function runCursorContext(): void {
|
||||
let editor = 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 cursorPos : Position = editor.selection.active;
|
||||
const text : string = editor.document.lineAt(cursorPos).text;
|
||||
const windowSize: number = vscode.workspace.getConfiguration('mindReader').get('reader.contextWindow')!;
|
||||
|
||||
let trimmedText = text.trimStart(); // trim leading whitespace
|
||||
let leadingWS = text.length - trimmedText.length; // # of characters of leading whitespace
|
||||
trimmedText = trimmedText.trimEnd(); // trim trailing whitespace
|
||||
let pos = leadingWS;
|
||||
let maxPos = text.length;
|
||||
|
||||
const windowSize : any = workspace.getConfiguration('mind-reader').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 = 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
|
||||
|
||||
if (col < leadingWS) {
|
||||
// move effective start to first non-whitespace character in the line
|
||||
col = leadingWS;
|
||||
} else if (col > leadingWS + trimmedText.length - 1) {
|
||||
}
|
||||
else if (col > leadingWS + trimmedText.length - 1) {
|
||||
// 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: {word: string, start: number, end: number}[] = [];
|
||||
const spaceWords: any[] = [];
|
||||
|
||||
while (pos < maxPos && trimmedText.length > 0) {
|
||||
let word = trimmedText.replace(/ .*/, '');
|
||||
spaceWords.push({word, start: pos, end: pos+word.length});
|
||||
const word: string = trimmedText.replace(/ .*/, '');
|
||||
|
||||
spaceWords.push({
|
||||
word,
|
||||
start: pos,
|
||||
end: pos + word.length
|
||||
});
|
||||
|
||||
// remove processed word from trimmed text
|
||||
const oldText = trimmedText;
|
||||
const oldText: string = trimmedText;
|
||||
trimmedText = trimmedText.replace(/[^ ]+/, '').trimStart();
|
||||
|
||||
// update pos to start of next word
|
||||
pos += oldText.length - trimmedText.length;
|
||||
}
|
||||
|
||||
// find word the user is in
|
||||
let contextStart: number = -1, contextEnd: number = -1;
|
||||
for (let i = 0; i < spaceWords.length; i++) {
|
||||
let contextStart: number = -1;
|
||||
let contextEnd : number = -1;
|
||||
|
||||
for (let i: number = 0; i < spaceWords.length; i++) {
|
||||
if (col >= spaceWords[i].start && col <= spaceWords[i].end) {
|
||||
// found the word
|
||||
contextStart = Math.max(0, i - windowSize); // clamp start index
|
||||
contextEnd = Math.min(spaceWords.length, i + windowSize + 1); // clamp end index
|
||||
|
||||
// construct cursor context string
|
||||
let contextString = '';
|
||||
for (let i = contextStart; i < contextEnd; i++) {
|
||||
let contextString: string = '';
|
||||
|
||||
for (let i: number = contextStart; i < contextEnd; i++) {
|
||||
contextString += spaceWords[i].word + ' ';
|
||||
}
|
||||
|
||||
// output cursor context string
|
||||
vscode.window.showInformationMessage(contextString);
|
||||
|
||||
window.showInformationMessage(contextString);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
31
src/ev3Manager.ts
Normal file
31
src/ev3Manager.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import * as vscode from 'vscode';
|
||||
//import * as fs from 'fs';
|
||||
//import { logger } from './extension';
|
||||
|
||||
|
||||
|
||||
export default class EV3Manager {
|
||||
private ev3devBrowser: vscode.Extension<any> | undefined = vscode.extensions.getExtension("ev3dev.ev3dev-browser");
|
||||
|
||||
private constructor() {}
|
||||
public test() {
|
||||
//console.log(this.ev3devBrowser);
|
||||
// This seems to be the only thing we, as an extension,
|
||||
// are allowed to do with this other extension.
|
||||
vscode.commands.executeCommand("ev3devBrowser.action.pickDevice", null);
|
||||
}
|
||||
public static activate(): Promise<EV3Manager> {
|
||||
return new Promise (async (resolve) => {
|
||||
try {
|
||||
let mgr = new EV3Manager();
|
||||
// Wait for ev3devBrowser to start
|
||||
await mgr.ev3devBrowser?.activate();
|
||||
// Return ev3Manager
|
||||
return resolve(mgr);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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 product: string = vscode.workspace.getConfiguration("mind-reader").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() {}
|
||||
|
@ -76,12 +76,14 @@ export default class HubManager {
|
||||
|
||||
// get full lines in buffer
|
||||
|
||||
let msgs = this.receiveBuffer.split(/\r/); // split by newline
|
||||
let msgs = this.receiveBuffer.split(/[\r>]/); // split by newline
|
||||
this.receiveBuffer = msgs.pop()!; // store unhandled data
|
||||
|
||||
msgs = msgs.filter(x => !x.startsWith('{"m":0,"p":')); // drop sensor broadcast response spam
|
||||
msgs = msgs.filter(x => !x.match(/{"m":\d+,"p":/)); // drop sensor broadcast response spam
|
||||
|
||||
for (const msg of msgs) {
|
||||
// check if message is actually json
|
||||
if (!msg.includes("{")) { continue; }
|
||||
// check if this msg is a response to a pending request
|
||||
try {
|
||||
let json: { [key: string]: any };
|
||||
@ -112,11 +114,15 @@ export default class HubManager {
|
||||
case 'runtime_error':
|
||||
logger.error(Buffer.from(params[3], 'base64').toString());
|
||||
break;
|
||||
case 2:
|
||||
logger.info(`Battery at ${params[0]}V`);
|
||||
break;
|
||||
}
|
||||
vscode.window.showErrorMessage("Program Error.");
|
||||
console.log(`Program error: ${msg}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Could not parse JSON:', msg);
|
||||
console.log('Could not parse JSON:', msg, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
311
src/lineHighlighter.ts
Normal file
311
src/lineHighlighter.ts
Normal file
@ -0,0 +1,311 @@
|
||||
/**
|
||||
* ? ██╗ ██╗██╗ ██████╗ ██╗ ██╗██╗ ██╗ ██████╗ ██╗ ██╗████████╗ ██╗████████╗
|
||||
* ? ██║ ██║██║██╔════╝ ██║ ██║██║ ██║██╔════╝ ██║ ██║╚══██╔══╝ ██║╚══██╔══╝
|
||||
* ? ███████║██║██║ ███╗███████║██║ ██║██║ ███╗███████║ ██║ █████╗██║ ██║
|
||||
* ? ██╔══██║██║██║ ██║██╔══██║██║ ██║██║ ██║██╔══██║ ██║ ╚════╝██║ ██║
|
||||
* ? ██║ ██║██║╚██████╔╝██║ ██║███████╗██║╚██████╔╝██║ ██║ ██║ ██║ ██║
|
||||
* ? ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
||||
* ! Initial Setup:
|
||||
* ! Open settings.json (ctrl+shift+p type 'settings' choose: 'Preferences: Open Settings (JSON))
|
||||
* ! Add the following to the bottom (may have to add a comma to the line above if it's not there, also remove the *s):
|
||||
* "mind-reader.lineHighlighter.isEnabled" : true,
|
||||
* "mind-reader.lineHighlighter.multiLineIsEnabled" : false,
|
||||
*
|
||||
* "mind-reader.lineHighlighter.backgroundColor" : "#232C5C",
|
||||
|
||||
* "mind-reader.lineHighlighter.outlineColor" : "#4866FE",
|
||||
* "mind-reader.lineHighlighter.outlineWidth" : "1px",
|
||||
* "mind-reader.lineHighlighter.outlineStyle" : "solid",
|
||||
*
|
||||
* "mind-reader.lineHighlighter.borderColorTop" : "#FFFFFF",
|
||||
* "mind-reader.lineHighlighter.borderColorRight" : "#FFFFFF",
|
||||
* "mind-reader.lineHighlighter.borderColorBottom" : "#FFFFFF",
|
||||
* "mind-reader.lineHighlighter.borderColorLeft" : "#FFFFFF",
|
||||
*
|
||||
* "mind-reader.lineHighlighter.borderWidthTop" : "1px",
|
||||
* "mind-reader.lineHighlighter.borderWidthRight" : "16px",
|
||||
* "mind-reader.lineHighlighter.borderWidthBottom" : "1px",
|
||||
* "mind-reader.lineHighlighter.borderWidthLeft" : "1px",
|
||||
*
|
||||
* "mind-reader.lineHighlighter.borderStyleTop" : "solid",
|
||||
* "mind-reader.lineHighlighter.borderStyleRight" : "solid",
|
||||
* "mind-reader.lineHighlighter.borderStyleBottom" : "solid",
|
||||
* "mind-reader.lineHighlighter.borderStyleLeft" : "solid",
|
||||
*
|
||||
* "mind-reader.lineHighlighter.fontStyle" : "normal",
|
||||
* "mind-reader.lineHighlighter.fontWeight" : "bolder",
|
||||
* "mind-reader.lineHighlighter.textColor" : "#FFFFFF",
|
||||
*
|
||||
* ! Restart VSCode for changes to take effect (if they didn't automatically)
|
||||
* ! Afterwards you can now edit using the settings window, or manually edit them
|
||||
* ! directly in settings.json by editing the values.
|
||||
*
|
||||
* TODO: FEATURE: Add ability for user to change options through a command pallette configurator
|
||||
* TODO: FEATURE: Add hotkey to toggle linehighlighter on/off
|
||||
* TODO: BUG: Adding the settings configurator made default settings break (if no values are found in settings.json)
|
||||
**/
|
||||
'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();
|
||||
}
|
||||
}
|
@ -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
|
||||
},
|
||||
@ -56,6 +55,18 @@ const rules: Rule[] = [
|
||||
pattern: /^\s*with\s+(?<attr>[^:]+):\s*$/,
|
||||
type: Symbol.WITH
|
||||
},
|
||||
{
|
||||
pattern: /^\s*#+\s*(?<attr>.*)\s*$/,
|
||||
type: Symbol.COMMENT
|
||||
},
|
||||
{
|
||||
pattern: /^\s*$/,
|
||||
type: Symbol.EMPTY
|
||||
},
|
||||
{
|
||||
pattern: /^\s*(?<attr>[^#]+)+\s*$/,
|
||||
type: Symbol.STATEMENT
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
@ -66,29 +77,6 @@ export default class Lexer {
|
||||
private pos : number = 0;
|
||||
private _currToken: LineToken = EOFTOKEN;
|
||||
|
||||
/**
|
||||
* Calculates indentation level for a line. If using soft tabs,
|
||||
* indent level rounds up (so, tabSize+1 spaces is 2 levels,
|
||||
* 2*tabSize+1 is 3, etc.)
|
||||
*
|
||||
* @param `text` The line of text.
|
||||
* @param `tabFmt` A tab information descriptor.
|
||||
* @return The indent of `text` with consideration for `tabFmt`.
|
||||
*/
|
||||
static getIndent(text: string, tabFmt: TabInfo): number {
|
||||
let leadingSpace: number = text.length - text.trimLeft().length;
|
||||
let indent: number;
|
||||
if (tabFmt.hard) {
|
||||
// used tabs
|
||||
indent = leadingSpace;
|
||||
} else {
|
||||
// use spaces
|
||||
indent = Math.ceil(leadingSpace/tabFmt.size!);
|
||||
}
|
||||
|
||||
return indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param `text` The text to lex.
|
||||
* @param `tabFmt` A tab information descriptor
|
||||
@ -96,7 +84,10 @@ export default class Lexer {
|
||||
constructor(text ? : string, private tabFmt ? : TabInfo) {
|
||||
// default is 4 wide expanded tabs
|
||||
this.tabFmt = {
|
||||
...{size: 4, hard: false},
|
||||
...{
|
||||
size: 4,
|
||||
hard: false
|
||||
},
|
||||
...tabFmt
|
||||
};
|
||||
|
||||
@ -124,7 +115,9 @@ export default class Lexer {
|
||||
/**
|
||||
* @return the current {@link LineToken}.
|
||||
*/
|
||||
currToken(): LineToken { return this._currToken; }
|
||||
currToken(): LineToken {
|
||||
return this._currToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance the position in the token stream.
|
||||
@ -138,12 +131,13 @@ export default class Lexer {
|
||||
|
||||
// Until a LineToken is found, or EOF
|
||||
while (this.pos < this.textLines.length) {
|
||||
let line: string = this.textLines[this.pos];
|
||||
let indent: number = Lexer.getIndent(line, this.tabFmt!);
|
||||
const line : string = this.textLines[this.pos];
|
||||
const indent: number = Lexer.getIndent(line, this.tabFmt!);
|
||||
let token : LineToken;
|
||||
|
||||
for (var r of rules) {
|
||||
// Does line match pattern?
|
||||
let match: RegExpMatchArray | null = line.match(r.pattern);
|
||||
const match: RegExpMatchArray | null = line.match(r.pattern);
|
||||
if (match) {
|
||||
// Yes...
|
||||
if (match.groups) {
|
||||
@ -154,28 +148,22 @@ export default class Lexer {
|
||||
|
||||
this._currToken = token;
|
||||
this.pos++;
|
||||
|
||||
return this.currToken();
|
||||
}
|
||||
}
|
||||
// No rules matched
|
||||
|
||||
// TODO: move to rules
|
||||
if (/^\s*(#.*)?$/.test(line)) {
|
||||
// "empty" line
|
||||
token = new LineToken(Symbol.EMPTY, this.pos, 999999);
|
||||
} else {
|
||||
// This is an INDENT token
|
||||
token = new LineToken(Symbol.INDENT, this.pos, indent);
|
||||
}
|
||||
|
||||
token = new LineToken(Symbol.INVALID, this.pos, 999999);
|
||||
this._currToken = token;
|
||||
this.pos++;
|
||||
|
||||
return this.currToken();
|
||||
}
|
||||
|
||||
// Didn't return, must be EOF
|
||||
this._currToken = EOFTOKEN;
|
||||
this.pos++;
|
||||
|
||||
return this.currToken();
|
||||
}
|
||||
|
||||
@ -210,6 +198,61 @@ export default class Lexer {
|
||||
}
|
||||
c--;
|
||||
}
|
||||
|
||||
return this.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates indentation level for a line. If using soft tabs,
|
||||
* indent level rounds up (so, tabSize+1 spaces is 2 levels,
|
||||
* 2*tabSize+1 is 3, etc.)
|
||||
*
|
||||
* @param `text` The line of text.
|
||||
* @param `tabFmt` A tab information descriptor.
|
||||
* @return The indent of `text` with consideration for `tabFmt`.
|
||||
*/
|
||||
static getIndent(text: string, tabFmt: TabInfo): number {
|
||||
const leadingSpace: number = text.length - text.trimStart().length;
|
||||
let indent: number;
|
||||
|
||||
if (tabFmt.hard) {
|
||||
// used tabs
|
||||
indent = leadingSpace;
|
||||
}
|
||||
else {
|
||||
// used spaces
|
||||
//? indent = Math.round(leadingSpace / tabFmt.size! * 10) / 10; // fractional indentation support?
|
||||
indent = Math.ceil(leadingSpace / tabFmt.size!);
|
||||
}
|
||||
|
||||
return indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates leading spaces for a line.
|
||||
* This method uses arithmetic to calculate the number of leading spaces
|
||||
*
|
||||
* @param `line` The line of text.
|
||||
* @return The number of leading spaces of `text`.
|
||||
*/
|
||||
static getLeadingSpacesByArithmetic(line: any): number {
|
||||
const leadingSpaces: number = line.text.length - line.text.trimStart().length;
|
||||
|
||||
return leadingSpaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates leading spaces for a line.
|
||||
* This method finds the index position of the first non-whitespace character
|
||||
* Since the index is built using a 0-index, the position of this character
|
||||
* will equal the number of spaces preceding the character.
|
||||
*
|
||||
* @param `text` The line of text.
|
||||
* @return The number of leading spaces of `text` with respect to the index position of the first non-whitespace character.
|
||||
*/
|
||||
static getLeadingSpacesByIndex(text: any): number {
|
||||
const indexNum: number = text.firstNonWhitespaceCharacterIndex;
|
||||
|
||||
return indexNum;
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,9 @@ export default class Parser {
|
||||
return children;
|
||||
}
|
||||
|
||||
if (this.lexer.currToken().type === Symbol.INDENT ||
|
||||
this.lexer.currToken().type === Symbol.EMPTY) {
|
||||
if (this.lexer.currToken().type === Symbol.STATEMENT ||
|
||||
this.lexer.currToken().type === Symbol.EMPTY ||
|
||||
this.lexer.currToken().type === Symbol.INVALID) {
|
||||
const label = this.lexer.currToken().type;
|
||||
// regular code, advance and stay in same block
|
||||
children.push(new LexNode(
|
||||
|
@ -16,8 +16,10 @@ export enum Symbol {
|
||||
EXCEPT = "except",
|
||||
FINALLY = "finally",
|
||||
WITH = "with",
|
||||
INDENT = "INDENT", // Indent token, default if not EOF, only contains indent information
|
||||
STATEMENT = "statement", // Indent token, contains non-empty code lines
|
||||
COMMENT = "Comment",
|
||||
EMPTY = "EMPTY", // empty line, used only to associate with the previous line
|
||||
INVALID = "INVALID",
|
||||
EOF = "EOF"
|
||||
}
|
||||
|
||||
@ -53,7 +55,7 @@ export default class LineToken {
|
||||
* @return A string representation of the token
|
||||
*/
|
||||
toString(): string {
|
||||
return this.type + ", linenr:" + (this.linenr+1) + ", indentLevel: " + this.indentLevel + ", attr: " + this.attr;
|
||||
return `${this.type}, linenr: ${this.linenr+1}, indentLevel: ${this.indentLevel}, attr: ${this.attr}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ suite('Lexer Test Suite', () => {
|
||||
});
|
||||
|
||||
test('Empty String', () => {
|
||||
let l: Lexer = new Lexer(undefined);
|
||||
let l: Lexer = new Lexer("");
|
||||
assert.deepStrictEqual(l.currToken(), EOFTOKEN);
|
||||
});
|
||||
|
||||
@ -22,18 +22,19 @@ suite('Lexer Test Suite', () => {
|
||||
});
|
||||
|
||||
test('Whitespace', () => {
|
||||
let l: Lexer = new Lexer(' \t\t'.repeat(4).repeat(4));
|
||||
assert.deepStrictEqual(l.currToken(), new LineToken(Symbol.EMPTY, 0, 999999));
|
||||
let s: string = ' '.repeat(4).repeat(4);
|
||||
let l: Lexer = new Lexer(s);
|
||||
assert.deepStrictEqual(l.currToken(), new LineToken(Symbol.EMPTY, 0, s.length/4));
|
||||
});
|
||||
|
||||
test('Comment', () => {
|
||||
let l: Lexer = new Lexer('# ur mom eats toes');
|
||||
assert.deepStrictEqual(l.currToken(), new LineToken(Symbol.EMPTY, 0, 999999));
|
||||
let l: Lexer = new Lexer('# this is a comment');
|
||||
assert.deepStrictEqual(l.currToken(), new LineToken(Symbol.COMMENT, 0, 0, 'this is a comment'));
|
||||
});
|
||||
|
||||
test('Non-Whitespace with no construct', () => {
|
||||
let l: Lexer = new Lexer('foobar');
|
||||
assert.deepStrictEqual(l.currToken(), new LineToken(Symbol.INDENT, 0, 0));
|
||||
assert.deepStrictEqual(l.currToken(), new LineToken(Symbol.STATEMENT, 0, 0, 'foobar'));
|
||||
});
|
||||
|
||||
test('getIndent() accuracy, spaces', () => {
|
||||
@ -50,10 +51,13 @@ suite('Lexer Test Suite', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('getIndent() accuracy, spaces with incomplete tab', () => {
|
||||
test('getIndent() accuracy, spaces with incomplete indentation', () => {
|
||||
let size: number = 4;
|
||||
for (var i = 0; i < 100; i++) {
|
||||
for (var j = 1; j <= 3; j++) {
|
||||
let l: Lexer = new Lexer(' '.repeat(i) + ' '.repeat(j) + 'foobar', {size: 4, hard: false});
|
||||
let l: Lexer = new Lexer(' '.repeat(i) + ' '.repeat(j) + 'foobar', {size: size, hard: false});
|
||||
// TODO: Swap these out when fractional indentation is used
|
||||
//assert.strictEqual(l.currToken().indentLevel, i + (Math.round(j / size * 100) / 100));
|
||||
assert.strictEqual(l.currToken().indentLevel, i + 1);
|
||||
}
|
||||
}
|
||||
@ -150,7 +154,7 @@ suite('Lexer Test Suite', () => {
|
||||
test('retract() 1-100', () => {
|
||||
let lines: string[] = Array.from(Array(100), (_, i) => 'line' + i);
|
||||
let reference: LineToken[] = lines.map((_, i) => {
|
||||
return new LineToken(Symbol.INDENT, i, 0);
|
||||
return new LineToken(Symbol.STATEMENT, i, 0, `line${i}`);
|
||||
});
|
||||
|
||||
for (var i = 0; i < 100; i++) {
|
||||
@ -169,7 +173,7 @@ suite('Lexer Test Suite', () => {
|
||||
test('2 full lex and retract passes', () => {
|
||||
let lines: string[] = Array.from(Array(100), (_, i)=> 'line' + i);
|
||||
let reference: LineToken[] = lines.map((_, i) => {
|
||||
return new LineToken(Symbol.INDENT, i, 0);
|
||||
return new LineToken(Symbol.STATEMENT, i, 0, `line${i}`);
|
||||
});
|
||||
|
||||
let l: Lexer = new Lexer(lines.join('\n'));
|
||||
|
@ -13,7 +13,7 @@ suite('LexNode Test Suite', () => {
|
||||
});
|
||||
|
||||
test('children() of leaf', () => {
|
||||
let n: LexNode = new LexNode('leafLexNode', vscode.TreeItemCollapsibleState.None, new LineToken(Symbol.INDENT, 0, 0));
|
||||
let n: LexNode = new LexNode('leafLexNode', vscode.TreeItemCollapsibleState.None, new LineToken(Symbol.STATEMENT, 0, 0));
|
||||
assert.strictEqual(n.children(), null);
|
||||
});
|
||||
|
||||
|
@ -7,7 +7,7 @@ import LexNode from '../../../pylex/node';
|
||||
import LineToken from '../../../pylex/token';
|
||||
import { Symbol } from '../../../pylex/token';
|
||||
|
||||
import { root,indent,empty } from '../../util';
|
||||
import { root, statement } from '../../util';
|
||||
|
||||
/**
|
||||
* Test Descriptor
|
||||
@ -23,23 +23,24 @@ const tests: ParserTest[] = [
|
||||
{ name: 'Single Empty Line', input: [''], output: root(null) },
|
||||
{
|
||||
name: 'Single Whitespace Only Line',
|
||||
input: [' '],
|
||||
input: [' '], // length 20
|
||||
output: root([
|
||||
empty(0)
|
||||
new LexNode(Symbol.EMPTY, 0, new LineToken(Symbol.EMPTY, 0, 20 / 4)) // 4 spaces per indent
|
||||
])
|
||||
},
|
||||
{
|
||||
name: 'Single Comment Only Line',
|
||||
input: ['# ur mom likes peas'],
|
||||
input: ['# this is a comment'],
|
||||
output: root([
|
||||
empty(0)
|
||||
new LexNode(Symbol.EMPTY, 0, new LineToken(Symbol.COMMENT, 0, 0, "this is a comment"))
|
||||
])
|
||||
},
|
||||
{
|
||||
name: 'Single Non-Control Line',
|
||||
input: ['my_age = 42'],
|
||||
output: root([
|
||||
indent(0, 0)
|
||||
//statement(0, 0)
|
||||
new LexNode("name", 0, new LineToken(Symbol.STATEMENT, 0, 0, 'my_age = 42'))
|
||||
])
|
||||
},
|
||||
{
|
||||
@ -55,7 +56,10 @@ const tests: ParserTest[] = [
|
||||
'bar = "Blue M&Ms make me happy <:)"',
|
||||
'reba = "A hard working gal"'
|
||||
],
|
||||
output: root([indent(0,0), indent(1,0)]),
|
||||
output: root([
|
||||
new LexNode("name", 0, new LineToken(Symbol.STATEMENT, 0, 0, 'bar = "Blue M&Ms make me happy <:)"')),
|
||||
new LexNode("name", 0, new LineToken(Symbol.STATEMENT, 1, 0, 'reba = "A hard working gal"'))
|
||||
]),
|
||||
},
|
||||
|
||||
{
|
||||
@ -66,11 +70,13 @@ const tests: ParserTest[] = [
|
||||
'billy = "Scrubbly Bubbles!"'
|
||||
],
|
||||
output: root([
|
||||
new LexNode('if radioshack',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LexNode('if radioshack', 0,
|
||||
new LineToken(Symbol.IF, 0, 0, 'radioshack'),
|
||||
[indent(1, 1)]),
|
||||
indent(2, 0)
|
||||
[
|
||||
new LexNode('print radioshack.hours', 0, new LineToken(Symbol.STATEMENT, 1, 1, 'print radioshack.hours'))
|
||||
]
|
||||
),
|
||||
new LexNode('billy = "Scrubbly Bubbles!"', 0, new LineToken(Symbol.STATEMENT, 2, 0, 'billy = "Scrubbly Bubbles!"'))
|
||||
])
|
||||
},
|
||||
|
||||
@ -82,11 +88,12 @@ const tests: ParserTest[] = [
|
||||
' print radioshack.hours'
|
||||
],
|
||||
output: root([
|
||||
indent(0, 0),
|
||||
new LexNode('if radioshack',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.IF, 1, 0, 'radioshack'),
|
||||
[indent(2, 1)])
|
||||
new LexNode('billy = "Scrubbly Bubbles!"', 0, new LineToken(Symbol.STATEMENT, 0, 0, 'billy = "Scrubbly Bubbles!"')),
|
||||
new LexNode('if radioshack', 0, new LineToken(Symbol.IF, 1, 0, 'radioshack'),
|
||||
[
|
||||
new LexNode('print radioshack.hours', 0, new LineToken(Symbol.STATEMENT, 2, 1, 'print radioshack.hours'))
|
||||
]
|
||||
)
|
||||
])
|
||||
},
|
||||
|
||||
@ -101,15 +108,18 @@ const tests: ParserTest[] = [
|
||||
' print("You really eat this?")',
|
||||
],
|
||||
output: root([
|
||||
new LexNode('if yummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.IF, 0, 0, 'yummy'), [indent(1, 1)]),
|
||||
new LexNode('elif just_ok',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.ELIF, 2, 0, 'just_ok'), [indent(3, 1)]),
|
||||
new LexNode('else',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.ELSE, 4, 0), [indent(5,1)]),
|
||||
new LexNode('if yummy', 0, new LineToken(Symbol.IF, 0, 0, 'yummy'),
|
||||
[
|
||||
statement(1, 1, 'print("HOoray!")')
|
||||
]),
|
||||
new LexNode('elif just_ok', 0, new LineToken(Symbol.ELIF, 2, 0, 'just_ok'),
|
||||
[
|
||||
statement(3, 1, 'print("Do you have anything else?")')
|
||||
]),
|
||||
new LexNode('else', 0, new LineToken(Symbol.ELSE, 4, 0),
|
||||
[
|
||||
statement(5, 1, 'print("You really eat this?")')
|
||||
]),
|
||||
])
|
||||
},
|
||||
|
||||
@ -122,13 +132,14 @@ const tests: ParserTest[] = [
|
||||
],
|
||||
output: root([
|
||||
new LexNode('if yummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
0,
|
||||
new LineToken(Symbol.IF, 0, 0, 'yummy'),
|
||||
[
|
||||
new LexNode('if in_my_tummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.IF, 1, 1, 'in_my_tummy'),
|
||||
[indent(2, 2)])
|
||||
new LexNode('if in_my_tummy', 0, new LineToken(Symbol.IF, 1, 1, 'in_my_tummy'),
|
||||
[
|
||||
statement(2, 2, 'exclaim("Scrumdiddlyumptious!")')
|
||||
]
|
||||
)
|
||||
],
|
||||
)
|
||||
])
|
||||
@ -141,23 +152,20 @@ const tests: ParserTest[] = [
|
||||
' if in_my_tummy:',
|
||||
' exclaim("Scrumdiddlyumptious!")',
|
||||
'else:',
|
||||
' exclaim("DAESGUSTEN~)"'
|
||||
' exclaim("DISGUSTING!")'
|
||||
],
|
||||
output: root([
|
||||
new LexNode('if yummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.IF, 0, 0, 'yummy'),
|
||||
new LexNode('if yummy', 0, new LineToken(Symbol.IF, 0, 0, 'yummy'),
|
||||
[
|
||||
new LexNode('if in_my_tummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.IF, 1, 1, 'in_my_tummy'),
|
||||
[indent(2, 2)])
|
||||
new LexNode('if in_my_tummy', 0, new LineToken(Symbol.IF, 1, 1, 'in_my_tummy'),
|
||||
[
|
||||
statement(2, 2, 'exclaim("Scrumdiddlyumptious!")')
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
new LexNode('else',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.ELSE, 3, 0),
|
||||
[indent(4, 1)]
|
||||
new LexNode('else', 0, new LineToken(Symbol.ELSE, 3, 0),
|
||||
[statement(4, 1, 'exclaim("DISGUSTING!")')]
|
||||
)
|
||||
])
|
||||
},
|
||||
@ -168,31 +176,27 @@ const tests: ParserTest[] = [
|
||||
'if yummy:',
|
||||
' if in_my_tummy:',
|
||||
' if looks_like_a_mummy:',
|
||||
' print("you have a spot on your tummy"',
|
||||
' print("you have a spot on your tummy")',
|
||||
'else:',
|
||||
' print("Food is food...")'
|
||||
],
|
||||
output: root([
|
||||
new LexNode('if yummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
0,
|
||||
new LineToken(Symbol.IF, 0, 0, 'yummy'),
|
||||
[
|
||||
new LexNode('if in_my_tummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.IF, 1, 1, 'in_my_tummy'),
|
||||
new LexNode('if in_my_tummy', 0, new LineToken(Symbol.IF, 1, 1, 'in_my_tummy'),
|
||||
[
|
||||
new LexNode('if looks_like_a_mummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LineToken(Symbol.IF, 2, 2, 'looks_like_a_mummy'),
|
||||
[indent(3, 3)])
|
||||
new LexNode('if looks_like_a_mummy', 0, new LineToken(Symbol.IF, 2, 2, 'looks_like_a_mummy'),
|
||||
[statement(3, 3, 'print("you have a spot on your tummy")')])
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
new LexNode('else',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
0,
|
||||
new LineToken(Symbol.ELSE, 4, 0),
|
||||
[indent(5, 1)]
|
||||
[statement(5, 1, 'print("Food is food...")')]
|
||||
)
|
||||
])
|
||||
},
|
||||
@ -203,44 +207,42 @@ const tests: ParserTest[] = [
|
||||
'if yummy:',
|
||||
' if in_my_tummy:',
|
||||
' if looks_like_a_mummy:',
|
||||
' print("you have a spot on your tummy"',
|
||||
' print("you have a spot on your tummy")',
|
||||
' else:',
|
||||
' print("eek! a zombie!)',
|
||||
' print("eek! a zombie!")',
|
||||
' elif in_my_mouth:',
|
||||
' print("itll be in my tummy soon!"',
|
||||
' print("itll be in my tummy soon!")',
|
||||
'else:',
|
||||
' print("Food is food...")'
|
||||
],
|
||||
output: root([
|
||||
new LexNode('if yummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LexNode('if yummy', 0,
|
||||
new LineToken(Symbol.IF, 0, 0, 'yummy'),
|
||||
[
|
||||
new LexNode('if in_my_tummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
new LexNode('if in_my_tummy', 0,
|
||||
new LineToken(Symbol.IF, 1, 1, 'in_my_tummy'),
|
||||
[
|
||||
new LexNode('if looks_like_a_mummy',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
0,
|
||||
new LineToken(Symbol.IF, 2, 2, 'looks_like_a_mummy'),
|
||||
[indent(3, 3)]),
|
||||
[statement(3, 3, 'print("you have a spot on your tummy")')]),
|
||||
new LexNode('else',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
0,
|
||||
new LineToken(Symbol.ELSE, 4, 2),
|
||||
[indent(5, 3)])
|
||||
[statement(5, 3, 'print("eek! a zombie!")')])
|
||||
]
|
||||
),
|
||||
new LexNode('elif in_my_mouth',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
0,
|
||||
new LineToken(Symbol.ELIF, 6, 1, 'in_my_mouth'),
|
||||
[indent(7, 2)]
|
||||
[statement(7, 2, 'print("itll be in my tummy soon!")')]
|
||||
)
|
||||
]
|
||||
),
|
||||
new LexNode('else',
|
||||
vscode.TreeItemCollapsibleState.None,
|
||||
0,
|
||||
new LineToken(Symbol.ELSE, 8, 0),
|
||||
[indent(9, 1)]
|
||||
[statement(9, 1, 'print("Food is food...")')]
|
||||
)
|
||||
])
|
||||
},
|
||||
@ -248,21 +250,24 @@ const tests: ParserTest[] = [
|
||||
name: 'Multiline Block',
|
||||
input: [
|
||||
'if yummy:',
|
||||
' print("you have a spot on your tummy"',
|
||||
' print("you have a spot on your tummy")',
|
||||
' print("eek! a zombie!)',
|
||||
' print("itll be in my tummy soon!"',
|
||||
' print("itll be in my tummy soon!")',
|
||||
'else:',
|
||||
' print("Food is food...")'
|
||||
],
|
||||
output: root([
|
||||
new LexNode('if yummy', 0, new LineToken(Symbol.IF, 0, 0, 'yummy'),
|
||||
[
|
||||
indent(1, 1),
|
||||
indent(2, 1),
|
||||
indent(3, 1),
|
||||
statement(1, 1, 'print("you have a spot on your tummy")'),
|
||||
statement(2, 1, 'print("eek! a zombie!)'),
|
||||
statement(3, 1, 'print("itll be in my tummy soon!")'),
|
||||
]
|
||||
),
|
||||
new LexNode('else', 0, new LineToken(Symbol.ELSE, 4, 0), [indent(5, 1)])
|
||||
new LexNode('else', 0, new LineToken(Symbol.ELSE, 4, 0),
|
||||
[
|
||||
statement(5, 1, 'print("Food is food...")')
|
||||
])
|
||||
])
|
||||
}
|
||||
];
|
||||
|
@ -50,19 +50,19 @@ function root(nodes: LexNode[] | null): LexNode {
|
||||
}
|
||||
|
||||
/* short hand for returning an indentation token for a certain line and indentation */
|
||||
function indent(linenr: number, indentLevel: number): LexNode {
|
||||
return new LexNode('INDENT', 0, new LineToken(PylexSymbol.INDENT, linenr, indentLevel));
|
||||
function statement(linenr: number, indentLevel: number, text: string = ""): LexNode {
|
||||
return new LexNode(PylexSymbol.STATEMENT, 0, new LineToken(PylexSymbol.STATEMENT, linenr, indentLevel, text));
|
||||
}
|
||||
|
||||
/* short hand for returning an empty token for a certain line*/
|
||||
function empty(linenr: number): LexNode {
|
||||
return new LexNode('EMPTY', 0, new LineToken(PylexSymbol.EMPTY, linenr, 999999));
|
||||
return new LexNode(PylexSymbol.EMPTY, 0, new LineToken(PylexSymbol.EMPTY, linenr, 999999));
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
deparent,
|
||||
root,
|
||||
indent,
|
||||
statement as statement,
|
||||
empty
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user