Compare commits

...

97 Commits

Author SHA1 Message Date
3253cc0b4b Reference developer install guide instead of the confusing mess 2022-05-10 14:11:18 -05:00
92c2a85497 TODO: Remove this when merging (OOPS!) 2022-05-10 14:10:02 -05:00
John Breaux
7087b99867
Merge pull request #6 from We-Dont-Byte/johnBreaux
Install vsce instead of yo and generator-code.
2022-05-10 12:29:11 -05:00
8dab64c956 "No newline at end of file" 2022-05-09 20:07:34 -05:00
bf494b639e Prepare extension for building
setup-development:
- linux:
  - Install vsce (visual studio code extension tool)
  - Don't install yo generator-code (unnecessary)
- windows:
  - Install vsce (see above)
  - Don't install uo generator-code
2022-05-09 20:03:24 -05:00
tel0065
faba55822c
Updated README
Updated the README with instructions on how to setup the line highlighter for the first time, added a table for the line highlighter options, added our team's contact information
2022-05-09 10:35:21 -05:00
tel0065
96b814a0de
Added Screenshot
Added screenshot of line highlighter settings.json file for use in the README
2022-05-09 10:34:10 -05:00
tel0065
fef2e8d63e
line missing
textDecoration line was missing from settings, added
2022-05-09 09:01:35 -05:00
53cc6bd056 Provide more descriptive group names for menu. 2022-05-07 23:49:13 -05:00
John Breaux
51b19a7054
Merge pull request #5 from We-Dont-Byte/johnBreaux
package.json:

    Remove duplicate entries
    Unify names of submenus according to Mind Reader naming conventions
    Add keybinds for things I accidentally only had in my User configuration (oops!)
    Reorganize right-click context menu to group similar commands
    Add keybinds for items in the right-click context menu (or replace them with vscode builtins)
2022-05-07 23:27:07 -05:00
b7679b1de2 Add keybinds for all important menu items
Some functions are not exposed by vscode on startup, so we must wrap them.
2022-05-07 23:20:07 -05:00
95dfce9d77 Reorganize right-click context menu
To reorganize the context menu,
- ${group: number}_name-of-group@${position_in_group: number}
2022-05-07 22:33:26 -05:00
a8542c6c88 package.json:
- Remove duplicate entries
- Unify names of submenus according to Mind Reader naming conventions
- Add keybinds for things I accidentally only had in my User configuration (oops!)
2022-05-07 22:00:34 -05:00
a9c43b1490 Update Mocha to version 10.0.0
Mocha 8.x relied on a vulnerable version of nanoid, which contained an info leak.
2022-05-07 21:29:59 -05:00
John Breaux
0a39522eca
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.
2022-05-07 21:16:29 -05:00
84f8e41737 Update Mind Reader dependencies 2022-05-07 20:34:47 -05:00
tel0065
5131db0a8a
added setup instructions
Added instructions as to how to setup for the first time to the comments section, added 2 more TODO items.
2022-05-07 13:31:34 -05:00
e7bdd356e3 Update permissions on install scripts, for linux. 2022-05-07 13:24:46 -05:00
3790d6c3a8 JSON booleans are not strings 2022-05-07 13:19:57 -05:00
7e001ee50c Only return cursor to editor when selection succeeds 2022-05-05 22:06:24 -05:00
7c985b3817 Stop forciby reselecting the document
Forcibly reselecting the document made using keyboard navigation inconvenient
2022-05-05 21:13:18 -05:00
8456f57b84 Mind_Reader -> Mind Reader
(except in URLs and critical identifiers)
2022-05-05 20:56:10 -05:00
3bffd6a9fd mindReader -> mind-reader 2022-05-05 20:49:15 -05:00
ec6b96bd9a Merge remote-tracking branch 'origin/thomasLane' into merge-johnbreaux-thomaslane 2022-05-05 19:49:29 -05:00
75d9762f41 Improve github actions CI 2022-05-05 18:44:50 -05:00
57b0d6b97e Don't reinstall w/ pacman 2022-05-05 17:08:48 -05:00
fecdf31c1f Visual Studio Code updated
New Electron version is 17.4.1
2022-05-05 16:45:48 -05:00
63d0b5aee3 Newline 2022-05-05 16:31:48 -05:00
e78470d6f7 Print progress information in install script. 2022-05-05 16:30:25 -05:00
9ef756838b Attempt fix setup script on Linux
Also update CC BY-SA notice of attribution
2022-05-05 16:12:55 -05:00
tel0065
be60f884fe
naming scheme
changed mindReader to mind-reader to be consistent with other parts of the extension
2022-05-05 12:15:39 -05:00
tel0065
b51507b76f
Version increase
Major version increase: 1.0.0 -> 2.0.0
2022-05-05 12:07:13 -05:00
tel0065
09b4d41054
Code cleaned
Removed commented out code
2022-05-05 11:59:42 -05:00
tel0065
c890e77d3c
Updated indention
Indention of ternary operator was incorrect, fixed
2022-05-05 11:57:54 -05:00
tel0065
a10200f2bc
Updated indention
Indention was incorrect, fixed.
2022-05-05 11:56:39 -05:00
tel0065
bb0b1be0d4
Updated Messages
Changed the wording of the loading message
2022-05-05 11:54:32 -05:00
tel0065
940a8ed317
Configuration Variables Updated
Updated configuration variables to match package.json calls, added TODO line at the top
2022-05-05 11:53:02 -05:00
tel0065
630391b5fe
Many Changes
Added settings for line highlighter, added contributors section, added bugs section, added homepage section, changed all instances of mindReader to mind-reader, changed all instances of Mind_Reader to Mind Reader
2022-05-05 11:51:12 -05:00
tel0065
cc8fbc26ad
Cleaned Up Code
Removed commented out code, added comments, etc
2022-05-04 19:40:33 -05:00
tel0065
af9308744b
added user config options
Added configuration options for the line highlighter feature
2022-05-04 19:28:10 -05:00
tel0065
cc1c23a16f
added function, fixed bug
Added function for selectLeadingSpaces, fixed bug which was reporting the wrong line number on some functions, added window focusing to most of the functions
2022-05-04 19:27:17 -05:00
tel0065
c17b718ce6
Added New Function
Added Senior Design Day Spring 2022 suggestion of selecting the leading whitespace characters. Had to refactor getLeadingWhitespace to include a helper function. Also added imports for vscode. Finally shifted helper functions together and added comments.
2022-05-01 20:22:26 -05:00
e0b2e5ee92 Update tests to match new behavior 2022-04-30 17:17:28 -05:00
34d89386ea Name improvements, new tokens, new behavior.
Name improvements:
- runLineContext changed to "Get Line Scope".
- runCursorContext changed to "Get Words Under Cursor".

New tokens:
- STATEMENT: Replaces INDENT. Stores entire line of python statement, not including comments, in attr.
- COMMENT: Stores entire comment line in attr.
- INVALID: Invalid token, used when parser can't figure out a line. Should never be seen.

New behavior:
- Get Line Scope now reads out the comment your cursor is in.
- Implemented fractional indentation notifications (disabled)
2022-04-30 17:12:36 -05:00
f86f2cb6b9 Powershellize the windows install-scripts
- Replace powershell aliases with canonical Cmdlet names
- Update function names to only use approved Verbs
2022-04-30 13:01:04 -05:00
971e6fe2fb hubmanager: receiveData:
Ignore numbered non-error status messages coming in on message channel
2022-04-29 02:46:42 -05:00
d5389c5ed3 Pacman is entirely broken. Oh well. 2022-04-29 02:45:05 -05:00
cc26efacd4 Node you fiendish beast, bow before my install script 2022-04-28 18:30:25 -05:00
97e54a5931 npm is a mess. 2022-04-28 18:16:33 -05:00
41b3c37ed3 Linux: Apt: Fix installation issues. 2022-04-28 18:10:31 -05:00
8266780775 fi 2022-04-28 17:43:21 -05:00
c2141e9c62 Ugh. 2022-04-28 17:41:19 -05:00
e749399793 Fix assignments in bash scripts 2022-04-28 17:38:47 -05:00
e8afacef18 Install scripts:
- Windows:
  - install:
    Move repo URI into variable
    Remove -NoWinget check (was unused)
  - upgrade:
    Change -NoWinget to disable updating with winget (can take a while)
    Create function to check install of node packages which are put on Path.
- Linux:
  - Install:
    Port install-windows to some linux distros
    Support for Apt (Ubuntu, possibly Debian/Mint)
    Support for Pacman (Arch/Manjaro/Garuda)
  - Upgrade:
    Port upgrade-windows to some linux distros
2022-04-28 17:30:55 -05:00
tel0065
2bbc5bce1f
Added lineHighlighter.ts 2022-04-27 12:07:33 -05:00
tel0065
34af001396
Deleted linehighlighter
wrong version
2022-04-27 12:07:13 -05:00
tel0065
77e55b1eb7
Deleted linehighlighter
Supposed to be added to my personal branch, not master.
2022-04-27 12:06:43 -05:00
tel0065
e023d6b680
Added linehighlighter
Added new linehighlighter to be used for extension
2022-04-27 12:05:46 -05:00
tel0065
dd10e928ef
updated webview 2022-04-27 12:01:44 -05:00
tel0065
5d3dc7acea
added new function
added fetchNumberOfSelectedLines and getNumberOfSelectedLines
2022-04-27 12:00:59 -05:00
tel0065
16869aa5b6
Added linehighlighter
added linehighlighter to be activated
2022-04-27 11:59:16 -05:00
tel0065
7d615c0bca
Added linehighlighter.ts 2022-04-27 11:58:14 -05:00
0634a90f58 Fix fresh install (Path was out of date) 2022-04-27 11:55:09 -05:00
tel0065
5a7fc30e4c
Update package.json 2022-04-27 11:55:01 -05:00
2948765ba8 Move install files to new directory
Open VSCode in the new repo after installation
2022-04-26 02:41:15 -07:00
40778b52fc Finish installation by opening VSCode 2022-04-26 02:19:14 -07:00
3d9eac7350 install: hotpatch
Fixes Visual Studio Build Tools installation
2022-04-26 02:01:13 -07:00
1f25b3c787 setup-development:
upgrade-windows.ps1:
    Update NodeJS, NVDA, VSCode, etc.
    Upbdate NPM dependencies
    If VSCode Electron ver. known, electron-rebuild with it
  install-windows.ps1
    Instal git
    Clone the mind-reader repo
    Run upgrade-windows.ps1 from the newly cloned repo
2022-04-26 01:19:31 -07:00
2fdd176dd6 createContextString:
Improve formatting somewhat
2022-04-24 02:34:03 -07:00
17c410eae2 Oops: Upload all files changed on VM in the last 5 days. Commit info lost. 2022-04-14 14:27:07 -05:00
de3c9bf435 ev3Manager:
- Start work on ev3 support
- Explore functionality of ev3dev-Browser
- Realize it's super limited
2022-04-09 21:19:11 -05:00
388cf1dfcf Update .gitignore 2022-04-09 21:14:56 -05:00
bcbd20a0bf package.json:
- Specify groups for commands
- Specify which LEGO Hub
- Clarify when keybinds should work
- Define keybinds for 'getLineNumber', 'runLineContext'
- Remove more redundant keybinds
2022-04-09 21:12:26 -05:00
bcfeb5a6fe package.json:
- Add titles for all mind-reader commands
- Remove redundant keybindings
- Redefine keybindings to no longer conflict with *VSCode*, JAWS, NVDA
2022-04-09 18:01:52 -05:00
cf0900968f Define types where previously any 2022-04-07 13:52:08 -05:00
tel0065
d19ad8f885
lexter.ts - let -> const, fixed type errors
changed most let variables to const, fixed more type errors
2022-03-25 13:17:51 -05:00
tel0065
50ff693d16
text.ts -> type error fixes, lets -> const, import
fixed type errors, changed most let variables to const, changed const require to imports
2022-03-25 13:09:16 -05:00
tel0065
3fed2aa4ad
text.ts -> removed random trailing spaces
Linter was complaining about trailing spaces in random places, removed them to get rid of the errors.
2022-03-25 11:13:08 -05:00
tel0065
ca3a5163fe
lexer.ts -> fixed type errors 2022-03-25 11:05:38 -05:00
tel0065
2f4800448b
text.ts -> fixed type errors 2022-03-25 11:03:06 -05:00
tel0065
a619146afc
lexter.ts - added types 2022-03-25 10:44:37 -05:00
tel0065
c087f1666a
text.ts - added types 2022-03-25 10:39:38 -05:00
tel0065
641997b620
delete lexer.js
.js file unintentionally uploaded, fixing that user error.
2022-03-25 09:12:55 -05:00
tel0065
829a3f0b9d
.js -> .ts
migrating changes made in .js file to .ts, .js file was unintended to be uploaded. User error to blame, fixing it.
2022-03-25 09:12:09 -05:00
tel0065
9062c253cf
delete text.js
.js file never supposed to have been uploaded, user error to blame. Removing it.
2022-03-25 09:09:09 -05:00
tel0065
96bca9a601
js -> ts migration
.js files ended up getting uploaded, beginnings of attempting to fix that mistake. Migrating changes made in .js file to .ts file
2022-03-25 09:08:07 -05:00
tel0065
125cf15a68
fixed plural output logic
Fixed logic of output, was showing singular for '0' ie: '0 space' instead of '0 spaces' - This has been resolved.
2022-03-24 04:48:59 -05:00
tel0065
88ddcd7c51
beautify code
ran beautify code extension to clean-up the code and make it more uniform in style
2022-03-24 04:28:21 -05:00
tel0065
08ec15287a
beautify code
ran beautify code extension to clean-up the code
2022-03-24 04:27:16 -05:00
tel0065
e67f731bc6
added 2 functions
added functions getLeadingSpacesByArithmetic and getLeadingSpacesByIndex to facilitate functionality of finding the number of leading spaces via two methods.
2022-03-24 04:03:17 -05:00
tel0065
d8c923e13c
Changed leading spaces logic
Added new logic to pl.Lexer to find number of leading spaces by either arithmetic or by finding the index position of the first non-whitespace character. Also added a boolean flag to switch easily between the two methods using ternary logic. Added comments explaining functionality. Fixed code spacing to be more uniform in style.
2022-03-24 04:01:24 -05:00
3525963bb0 Switch from string concatination to interpolation
Improves concision.
2022-03-23 22:53:46 -05:00
tel0065
6915cd5b44
leading spaces alternative method
Added an alternative method for calculating the leading spaces instead of taking the index of the first non-whitespace character. Leaving it commented out, but still there as an alternative  in-case something goes wrong w/ the index method.
2022-03-23 21:42:05 -05:00
tel0065
cfcbfd43fc
added fetchLineNumber(editor) and getLineNumber()
added helper function fetchLineNumber(editor) to return the line number that the cursor is on and refactored the code to make use of this helper function in various places. Also added function getLineNumber() which will output the current line number the cursor is on.
2022-03-23 18:20:44 -05:00
tel0065
d76cc3d06d
fixed output type-o on getLeadingSpaces()
Fixed issue with the output not displaying as intended in the getLeadingSpaces() function
2022-03-23 17:46:44 -05:00
tel0065
cac31ceaa9
added getLeadingSpaces() function
Added function that would return  the number of leading spaces on a line
2022-03-23 17:44:56 -05:00
Jake Grossman
30248966bf
Add contact information (#15)
* added change theme feature

* added change theme feature

* Add contact information

* Add contact email

* Added Contact Info

* added my contact info to readme

* Update README.md

Co-authored-by: sophiadrewfs <sophiadrewfs@gmail.com>
Co-authored-by: CalWooten95 <Cal.wooten95@gmail.com>
Co-authored-by: JosiahMoses <32985363+JosiahMoses@users.noreply.github.com>
2021-12-09 11:19:40 -06:00
29 changed files with 2490 additions and 955 deletions

View File

@ -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
View File

@ -2,4 +2,5 @@ out
dist
node_modules
.vscode-test/
*.code-workspace
*.vsix

View File

@ -10,3 +10,5 @@ vsc-extension-quickstart.md
**/.eslintrc.json
**/*.map
**/*.ts
setup-development/**

184
README.md
View File

@ -3,13 +3,13 @@
<img alt="Mind Reader Logo" src="media/logo.png"></img>
</p>
<h1>Mind_Reader</h1>
<h1>Mind Reader</h1>
<!-- overview description -->
The current editor options available lack the level of accessibility that is
required to allow people who are visually impaired to adequately write, edit,
and debug code.
and debug code.
This tool extends Visual Studio Codes existing
accessibility options to enable people with a visual impairment to learn
@ -21,7 +21,7 @@ Python programming with LEGO Mindstorms. Our goal is to:
## Major Features
- Compatibility with major screen readers:
- Compatible with major screen readers:
- [NVDA](https://www.nvaccess.org/)
- [JAWS](https://www.freedomscientific.com/products/software/jaws/)
@ -29,103 +29,119 @@ Python programming with LEGO Mindstorms. Our goal is to:
- Present a summary of the scope for an individual line of code.
- Save and load programs directly onto the LEGO Hub from within Visual Studio Code
- Save, Load, Run, and Delete programs directly onto the LEGO SPIKE Prime Hub from within Visual Studio Code
## Dependencies
- [Git](https://git-scm.com/)
- [Node.js](https://nodejs.org/en/)
- Line highlighting with customizable colors and formats
**NOTE**: While installing Node.js, there will be a section titled "Tools for Native Modules". Make sure that
'Automatically install the necessary tools' is checked:
# First Time Setting Up the Line Highlighter Feature
Before running Mind Reader for the first time it is recommended to add the following code block to your `settings.json` file
### Opening Settings.json
1. Launch VS Code
2. Open the `Command Palette` by pressing **Ctrl + Shift + P** (Windows) / **Cmd + Shift + P** (Mac)
3. The Command Palette should appear at the top of your screen ready for you to type
4. Type `settings` and highlight the option that appears saying `Preferences: Open Settings (JSON)` then select it
5. Your `settings.json` window should appear, scroll to the bottom and make sure the last item has a `,` before the closing curly bracket `}`
6. Paste the following code block after the last comma `,`, but before the closing curly bracket `}`:
```
"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.textDecoration" : "none",
"mind-reader.lineHighlighter.textColor" : "#FFFFFF",
```
The values are set to the default values and can be changed here manually, or through the settings window (File -> Preferences -> Settings -> Mind Reader -> Line Highlighter).
Changes made directly in the settings.json will take effect automatically; however, if you change them in the settings window then after you input your new values VS Code must be closed and reopened for the changes to take effect.
After adding the code block, the `settings.json` file should look similar to this:
<p align="center">
<img width="50%" height="50%" alt="tools for native modules page with tool installation checked" src="media/nodejs_setup.png"></img>
<img width="35%" height="35%" alt="line highlighter first time setup" src="media/line_highlighter_setup.PNG"></img>
</p>
If the compiled serial port version is incompatible, you may see no options presented in the Mind_Reader actions panel:
7. Save and close `settings.json`
<p align="center">
<img width="50%" height="50%" alt="mind reader actions panel with no items:" src="media/missing_actions.png"></img>
</p>
### Line Highlighter Settings Table
| **Item** | **Description** | **Accepted Value** | **Default Values** |
|------------------------|-------------------------------------------------------|------------------------------------------------------------------------------|--------------------|
| **isEnabled** | Enable/Disables the line highlighter | boolean | true |
| **multiLineIsEnabled** | Highlight when clicking and dragging to select lines | boolean | false |
| **backgroundColor** | Changes the background color of the highlight | HEX(A), RGB(A), HSL(A), Predefined Color String, or "none" | "#232C5C" |
| **outlineColor** | Outline Color | HEX(A), RGB(A), HSL(A), Predefined Color String, or "none" | "#4866FE" |
| **outlineWidth** | Outline Width | "medium", "thin", "thick", length (integer + string unit), or "none" | "1px" |
| **outlineStyle** | Outline Style | none, hidden, dotted, dashed, solid, double, groove, ridge, inset, or outset | "solid" |
| **borderColorTop** | Top Border Color | HEX(A), RGB(A), HSL(A), Predefined Color String, or "none" | "#FFFFFF" |
| **borderColorRight** | Right Border Color | HEX(A), RGB(A), HSL(A), Predefined Color String, or "none" | "#FFFFFF" |
| **borderColorBottom** | Bottom Border Color | HEX(A), RGB(A), HSL(A), Predefined Color String, or "none" | "#FFFFFF" |
| **borderColorLeft** | Left Border Color | HEX(A), RGB(A), HSL(A), Predefined Color String, or "none" | "#FFFFFF" |
| **borderWidthTop** | Top Border Width | "medium", "thin", "thick", length (integer + string unit), or "none" | "1px" |
| **borderWidthRight** | Right Border Width | "medium", "thin", "thick", length (integer + string unit), or "none" | "16px" |
| **borderWidthBottom** | Bottom Border Width | "medium", "thin", "thick", length (integer + string unit), or "none" | "1px" |
| **borderWidthLeft** | Left Border Width | "medium", "thin", "thick", length (integer + string unit), or "none" | "1px" |
| **borderStyleTop** | Top Border Style | none, hidden, dotted, dashed, solid, double, groove, ridge, inset, or outset | "solid" |
| **borderStyleRight** | Right Border Style | none, hidden, dotted, dashed, solid, double, groove, ridge, inset, or outset | "solid" |
| **borderStyleBottom** | Bottom Border Style | none, hidden, dotted, dashed, solid, double, groove, ridge, inset, or outset | "solid" |
| **borderStyleLeft** | Left Border Style | none, hidden, dotted, dashed, solid, double, groove, ridge, inset, or outset | "solid" |
| **fontStyle** | Styling to the font contained within the highlight | "normal", "italic", "oblique", or "none" | "normal" |
| **fontWeight** | Weight of the font contained within the highlight | "normal", "bold", "bolder", "lighter", string based number, "none" | "bolder" |
| **textDecoration** | Decoration of the font contained within the highlight | See: https://www.w3schools.com/cssref/pr_text_text-decoration.asp | "none" |
| **textColor** | Color of the font contained within the highlight | HEX(A), RGB(A), HSL(A), Predefined Color String, or "none" | "#FFFFFF" |
In this case, you will also need to rebuild the serial port component with `electron-rebuild`. This is a one-time setup
for each version of Visual Studio Code. You may need to repeat this process if you update your version of Visual Studio
Code.
## Installing `electron-rebuild`
**Use Git Bash on Windows, and the terminal on MacOS/Linux. These steps will refer to this as 'the terminal'**
### 1 Install the `electron-rebuild` tool
In the terminal install electron rebuild with `npm` that is included with [Node.js](https://nodejs.org/en/):
```console
$ npm install -g electron-rebuild
```
### 2 Finding your electron version
On MacOS, go to Code > About Visual Studio Code.
On Windows and Linux, go to Help > About.
The electron version should be listed, e.g.: `Electron: 13.5.2`
<p align="center">
<img width="35%" height="35%" alt="vscode information" src="media/vscode_info.png"></img>
</p>
### 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
e.g.: `~/.vscode/extensions`.
---
Find the Mind_Reader extension folder, this should look like `xxx.mind-reader-x.x.x`.
Navigate to the found folder in the terminal.
```console
$ cd ~/.vscode/extensions/<mind_reader_folder>
```
### 4 Running `electron-rebuild`
Then, run `electron-rebuild` with `ELECTRON_VERSION` replaced with the electron version found in step 2:
```console
$ electron-rebuild --version=ELECTRON_VERSION
```
# For Developers
## Development Quick Start
Use the following to set up the extension for development.
## Developer Dependencies
```console
$ git clone https://github.com/SingleSemesterSnobs/Mind_Reader.git
$ cd Mind_Reader
$ npm install
```
### Development environment setup guide
While inside the repository do
### Windows 10 or 11
* Download [install-windows.ps1](setup-development/windows/install-windows.ps1)
* Run `./install-windows.ps1` in PowerShell as a normal user, and accept any UAC prompts that pop up. The installation should take around 8 minutes. If an installer doesn't pop up, don't be alarmed.
```console
$ code .
```
For other platforms, or to install the extension manually, check out our [Developer Install Guide](../../wiki/Developer-Install-Guide). This is also where you should search if you encounter errors.
to open the cloned repository in VS Code.
Then, use "Run > Start Debugging" on the menu bar to start the [Extension
Development Host](https://code.visualstudio.com/api/advanced-topics/extension-host)
(<kbd>F5</kbd> by default).
---
If you get an error about a `NODE_MODULE_VERSION` incompatibility or that a file is not a Windows executable,
this is likely the error described above. Run `npm i -g electron-rebuild` if you have not done so and follow the
directions above.
---
See the Visual Studio Code [getting started](https://code.visualstudio.com/api/get-started/your-first-extension)
API page if you need more help.
# Contact Information
### Single Semester Snobs
#### Fall 2021 Semester
- Jake Grossman: [\<JacobGrossman2@my.unt.edu\>](mailto:JacobGrossman2@my.unt.edu)
- Cal Wooten: [\<calwooten@my.unt.edu\>](mailto:calwooten@my.unt.edu)
- Josiah Moses: [\<josiahmoses@my.unt.edu\>](mailto:josiahmoses@my.unt.edu)
- Sophia Drewfs: [\<sophiadrewfs@my.unt.edu\>](mailto:sophiadrewfs@my.unt.edu)
- Mason Bone: [\<masonbone@my.unt.edu\>](mailto:masonbone@my.unt.edu)
### We Don't Byte
#### Spring 2022 Semester
- John Breaux: [\<JohnBreaux@my.unt.edu\>](mailto:JohnBreaux@my.unt.edu)
- Thomas Lane: [\<ThomasLane2@my.unt.edu\>](mailto:ThomasLane2@my.unt.edu)
- Kendrick Johnson: [\<KendrickJohnson@my.unt.edu\>](mailto:KendrickJohnson@my.unt.edu)
- Ryan Tolbert: [\<RyanTolbert@my.unt.edu\>](mailto:RyanTolbert@my.unt.edu)
- Pedro Alvarez: [\<PedroAlvarez3@my.unt.edu\>](mailto:PedroAlvarez3@my.unt.edu)

View File

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

359
package-lock.json generated
View File

@ -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"
},
@ -21,12 +21,12 @@
"@vscode/test-electron": "^1.6.2",
"eslint": "^7.27.0",
"glob": "^7.1.7",
"mocha": "^8.4.0",
"mocha": "^10.0.0",
"typescript": "^4.3.2",
"vscode-test": "^1.5.2"
},
"engines": {
"vscode": "^1.60.0"
"vscode": "^1.66.0"
}
},
"node_modules/@babel/code-frame": {
@ -945,24 +945,30 @@
}
},
"node_modules/chokidar": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
],
"dependencies": {
"anymatch": "~3.1.1",
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.0",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.5.0"
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"optionalDependencies": {
"fsevents": "~2.3.1"
"fsevents": "~2.3.2"
}
},
"node_modules/chownr": {
@ -1035,9 +1041,9 @@
}
},
"node_modules/debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
@ -1745,15 +1751,6 @@
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"node_modules/growl": {
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
"dev": true,
"engines": {
"node": ">=4.x"
}
},
"node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -1937,6 +1934,18 @@
"node": ">=8"
}
},
"node_modules/is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@ -2032,15 +2041,19 @@
"dev": true
},
"node_modules/log-symbols": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
"integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dev": true,
"dependencies": {
"chalk": "^4.0.0"
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lru-cache": {
@ -2101,9 +2114,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",
@ -2123,43 +2136,40 @@
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"node_modules/mocha": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz",
"integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz",
"integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==",
"dev": true,
"dependencies": {
"@ungap/promise-all-settled": "1.1.2",
"ansi-colors": "4.1.1",
"browser-stdout": "1.3.1",
"chokidar": "3.5.1",
"debug": "4.3.1",
"chokidar": "3.5.3",
"debug": "4.3.4",
"diff": "5.0.0",
"escape-string-regexp": "4.0.0",
"find-up": "5.0.0",
"glob": "7.1.6",
"growl": "1.10.5",
"glob": "7.2.0",
"he": "1.2.0",
"js-yaml": "4.0.0",
"log-symbols": "4.0.0",
"minimatch": "3.0.4",
"js-yaml": "4.1.0",
"log-symbols": "4.1.0",
"minimatch": "5.0.1",
"ms": "2.1.3",
"nanoid": "3.1.20",
"serialize-javascript": "5.0.1",
"nanoid": "3.3.3",
"serialize-javascript": "6.0.0",
"strip-json-comments": "3.1.1",
"supports-color": "8.1.1",
"which": "2.0.2",
"wide-align": "1.1.3",
"workerpool": "6.1.0",
"workerpool": "6.2.1",
"yargs": "16.2.0",
"yargs-parser": "20.2.4",
"yargs-unparser": "2.0.0"
},
"bin": {
"_mocha": "bin/_mocha",
"mocha": "bin/mocha"
"mocha": "bin/mocha.js"
},
"engines": {
"node": ">= 10.12.0"
"node": ">= 14.0.0"
},
"funding": {
"type": "opencollective",
@ -2172,47 +2182,13 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"node_modules/mocha/node_modules/debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"node_modules/mocha/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/mocha/node_modules/debug/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"node_modules/mocha/node_modules/glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
"balanced-match": "^1.0.0"
}
},
"node_modules/mocha/node_modules/has-flag": {
@ -2225,9 +2201,9 @@
}
},
"node_modules/mocha/node_modules/js-yaml": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"dependencies": {
"argparse": "^2.0.1"
@ -2236,6 +2212,18 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/mocha/node_modules/minimatch": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/mocha/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@ -2268,9 +2256,9 @@
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
},
"node_modules/nanoid": {
"version": "3.1.20",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
"integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
"dev": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
@ -2595,9 +2583,9 @@
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/readdirp": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"dependencies": {
"picomatch": "^2.2.1"
@ -2728,9 +2716,9 @@
}
},
"node_modules/serialize-javascript": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
"integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
"integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
"dev": true,
"dependencies": {
"randombytes": "^2.1.0"
@ -2817,9 +2805,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 +3193,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"
}
@ -3253,9 +3241,9 @@
}
},
"node_modules/workerpool": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
"integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
"integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
"dev": true
},
"node_modules/wrap-ansi": {
@ -4016,19 +4004,19 @@
}
},
"chokidar": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"requires": {
"anymatch": "~3.1.1",
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"fsevents": "~2.3.1",
"glob-parent": "~5.1.0",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.5.0"
"readdirp": "~3.6.0"
}
},
"chownr": {
@ -4095,9 +4083,9 @@
}
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
@ -4632,12 +4620,6 @@
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"growl": {
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
"dev": true
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -4765,6 +4747,12 @@
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"dev": true
},
"is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
"dev": true
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@ -4848,12 +4836,13 @@
"dev": true
},
"log-symbols": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
"integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dev": true,
"requires": {
"chalk": "^4.0.0"
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
}
},
"lru-cache": {
@ -4896,9 +4885,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",
@ -4915,33 +4904,30 @@
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"mocha": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz",
"integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz",
"integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==",
"dev": true,
"requires": {
"@ungap/promise-all-settled": "1.1.2",
"ansi-colors": "4.1.1",
"browser-stdout": "1.3.1",
"chokidar": "3.5.1",
"debug": "4.3.1",
"chokidar": "3.5.3",
"debug": "4.3.4",
"diff": "5.0.0",
"escape-string-regexp": "4.0.0",
"find-up": "5.0.0",
"glob": "7.1.6",
"growl": "1.10.5",
"glob": "7.2.0",
"he": "1.2.0",
"js-yaml": "4.0.0",
"log-symbols": "4.0.0",
"minimatch": "3.0.4",
"js-yaml": "4.1.0",
"log-symbols": "4.1.0",
"minimatch": "5.0.1",
"ms": "2.1.3",
"nanoid": "3.1.20",
"serialize-javascript": "5.0.1",
"nanoid": "3.3.3",
"serialize-javascript": "6.0.0",
"strip-json-comments": "3.1.1",
"supports-color": "8.1.1",
"which": "2.0.2",
"wide-align": "1.1.3",
"workerpool": "6.1.0",
"workerpool": "6.2.1",
"yargs": "16.2.0",
"yargs-parser": "20.2.4",
"yargs-unparser": "2.0.0"
@ -4953,35 +4939,13 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"ms": "2.1.2"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
"balanced-match": "^1.0.0"
}
},
"has-flag": {
@ -4991,14 +4955,23 @@
"dev": true
},
"js-yaml": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"requires": {
"argparse": "^2.0.1"
}
},
"minimatch": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@ -5027,9 +5000,9 @@
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
},
"nanoid": {
"version": "3.1.20",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
"integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
"dev": true
},
"napi-build-utils": {
@ -5271,9 +5244,9 @@
}
},
"readdirp": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
@ -5342,9 +5315,9 @@
}
},
"serialize-javascript": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
"integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
"integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
@ -5405,9 +5378,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 +5688,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",
@ -5750,9 +5723,9 @@
"dev": true
},
"workerpool": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
"integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
"integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
"dev": true
},
"wrap-ansi": {

View File

@ -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,187 +61,238 @@
"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",
"category": "Mind Reader"
},
{
"command": "mind-reader.getIndent",
"title": "Get Line Indentation"
"title": "Get The Number Of Line Indentations",
"category": "Mind Reader"
},
{
"command": "mind-reader.getLeadingSpaces",
"title": "Get The Number Of Leading Spaces",
"category": "Mind Reader"
},
{
"command": "mind-reader.selectLeadingWhitespace",
"title": "Select The Leading Whitespace",
"category": "Mind Reader"
},
{
"command": "mind-reader.getNumberOfSelectedLines",
"title": "Get The Number Of Selected Lines",
"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"
},
{
"command": "mind-reader.connectHub",
"title": "Connect LEGO Hub"
"title": "Connect a LEGO SPIKE Prime Hub",
"category": "SPIKE Prime"
},
{
"command": "mind-reader.disconnectHub",
"title": "Disconnect LEGO Hub"
},
{
"command": "mind-reader.uploadCurrentFile",
"title": "Upload current file to LEGO Hub"
"title": "Disconnect a 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"
}
],
"keybindings": [
{
"command": "accessActions.focus",
"comment": "This opens the Access Actions menu",
"key": "Ctrl+Shift+/ Ctrl+Shift+/",
"mac": "Cmc+Shift+[Slash] Cmc+Shift+[Slash]"
},
{
"command": "mind-reader.decreaseFontScale",
"key": "numpad_subtract",
"mac": "d"
"key": "Shift+Alt+Z -",
"mac": "Cmd+Shift+Z -",
"when": "editorTextFocus"
},
{
"command": "mind-reader.increaseFontScale",
"key": "numpad_add",
"mac": "[NumpadAdd]"
"key": "Shift+Alt+Z =",
"mac": "Cmd+Shift+Z =",
"when": "editorTextFocus"
},
{
"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": "mind-reader.resetFontScale",
"key": "Shift+Alt+Z 0",
"mac": "Cmd+Shift+Z 0",
"when": "editorTextFocus"
},
{
"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 && editorLangId == python"
},
{
"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.getNumberOfSelectedLines",
"key": "Ctrl+Shift+/ N",
"mac": "Cmd+Shift+[Slash] N"
},
{
"command": "mind-reader.selectLeadingWhitespace",
"key": "Ctrl+Shift+/ W",
"mac": "Cmd+Shift+[Slash] W"
}
],
"menus": {
@ -207,112 +304,274 @@
],
"mind-reader.editor.context": [
{
"command": "mind-reader.increaseEditorScale",
"group": "mind-reader",
"command": "mind-reader.openKeybinds",
"group": "0_configuration@0",
"when": "activeEditor"
},
{
"command": "workbench.action.selectTheme",
"group": "0_configuration@1",
"when": "activeEditor"
},
{
"command": "mind-reader.increaseFontScale",
"group": "1_font-zoom@0",
"when": "activeEditor"
},
{
"command": "mind-reader.decreaseFontScale",
"group": "mind-reader",
"group": "1_font-zoom@1",
"when": "activeEditor"
},
{
"command": "mind-reader.resetFontScale",
"group": "mind-reader",
"group": "1_font-zoom@2",
"when": "activeEditor"
},
{
"command": "mind-reader.increaseEditorScale",
"group": "mind-reader",
"command": "workbench.action.zoomIn",
"group": "2_workbench-zoom@0",
"when": "activeEditor"
},
{
"command": "mind-reader.decreaseEditorScale",
"group": "mind-reader",
"command": "workbench.action.zoomOut",
"group": "2_workbench-zoom@1",
"when": "activeEditor"
},
{
"command": "mind-reader.resetEditorScale",
"group": "mind-reader",
"command": "workbench.action.zoomReset",
"group": "2_workbench-zoom@2",
"when": "activeEditor"
},
{
"command": "mind-reader.selectTheme",
"group": "mind-reader",
"command": "mind-reader.getLineNumber",
"group": "3_getter-functions@0",
"when": "activeEditor"
},
{
"command": "mind-reader.getIndent",
"group": "3_getter-functions@1",
"when": "activeEditor"
},
{
"command": "mind-reader.getLeadingSpaces",
"group": "3_getter-functions@2",
"when": "activeEditor"
},
{
"command": "mind-reader.getNumberOfSelectedLines",
"group": "3_getter-functions@3",
"when": "activeEditor"
},
{
"command": "mind-reader.selectLeadingWhitespace",
"group": "4_selector-functions@0",
"when": "activeEditor"
},
{
"command": "mind-reader.openWebview",
"group": "mind-reader",
"when": "activeEditor"
},
{
"command": "mind-reader.openKeyBindWin",
"group": "mind-reader",
"when": "activeEditor"
},
{
"command": "mind-reader.openKeyBindMac",
"group": "mind-reader",
"when": "activeEditor"
"group": "z_disabled@99",
"when": "false"
}
]
},
"submenus": [
{
"id": "mind-reader.editor.context",
"label": "Mind_Reader"
"label": "Mind Reader"
}
],
"configuration": {
"title": "Mind_Reader",
"properties": {
"mindReader.productType": {
"type": "string",
"description": "Specifies the LEGO® product.",
"default": "MINDSTORMS EV3",
"enum": [
"MINDSTORMS EV3",
"SPIKE Prime"
],
"enumDescriptions": [
"LEGO® MINDSTORMS® EV3 (31313)",
"LEGO® Education SPIKE™ Prime Set (45678)"
]
},
"mindReader.reader.screenReader": {
"type": "string",
"description": "Specifies which screen reader to optimize for.",
"default": "NVDA",
"enum": [
"NVDA",
"Orca",
"VoiceOver"
],
"enumDescriptions": [
"NonVisual Desktop Access (Windows)",
"Orca (Linux)",
"Apple VoiceOver (macOS)"
]
},
"mindReader.reader.contextWindow": {
"type": "number",
"description": "The number of words around the cursor to use when reading the cursor context",
"default": 1
},
"mindReader.connection.portPath": {
"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"
"configuration": [
{
"title": "Mind Reader",
"order": 0,
"properties": {
"mind-reader.productType": {
"order": 1,
"type": "string",
"description": "Specifies the LEGO® product.",
"default": "SPIKE Prime",
"enum": [
"MINDSTORMS EV3",
"SPIKE Prime"
],
"enumDescriptions": [
"LEGO® MINDSTORMS® EV3 (31313)",
"LEGO® Education SPIKE™ Prime Set (45678)"
]
},
"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)"
]
},
"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
},
"mind-reader.connection.portPath": {
"order": 2,
"type": "string",
"markdownDescription": "The default port to try and establish a connection on."
}
}
},
{
"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": [
"Mind-Reader": [
{
"id": "accessActions",
"name": "Access Actions",
@ -330,8 +589,8 @@
"viewsContainers": {
"activitybar": [
{
"id": "MindReader",
"title": "MindReader Actions",
"id": "Mind-Reader",
"title": "Mind Reader Actions",
"icon": "media/dep.svg"
}
]
@ -356,7 +615,7 @@
"@vscode/test-electron": "^1.6.2",
"eslint": "^7.27.0",
"glob": "^7.1.7",
"mocha": "^8.4.0",
"mocha": "^10.0.0",
"typescript": "^4.3.2",
"vscode-test": "^1.5.2"
},

View File

@ -0,0 +1,60 @@
#!/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"
cd "$gitdir/$setupdir"
bash ./upgrade-linux.sh $@
echo "Opening VS Code..."
cd $gitdir/Mind_Reader
code .

View File

@ -0,0 +1,4 @@
apt-transport-https
build-essential
python3
wget

View File

@ -0,0 +1,4 @@
base-devel
git
wget
python3

View 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 and vsce\n"
dryrun npm install -g electron-rebuild vsce
# 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!"

View File

@ -0,0 +1,173 @@
<#
.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'"
# 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)
}

View 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
}
}
# electron-rebuild is used to rebuild the extension for a given version of Electron
EnsureNodePackageInstalled electron-rebuild
# vsce is used to package the extension
EnsureNodePackageInstalled vsce
# 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)
}

View 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"
}

View File

@ -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[] = [];

View File

@ -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');
}
}

View File

@ -1,168 +1,388 @@
import * as vscode from 'vscode';
import * as pl from '../pylex';
import { CommandEntry } from './commandEntry';
"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.getIndent',
callback: getIndent,
},
{
name: 'mind-reader.getLineNumber',
callback: getLineNumber,
},
{
name: 'mind-reader.getIndent',
callback: getIndent,
},
{
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.getWordsUnderCursor',
callback: runCursorContext
}
];
{
name: 'mind-reader.runLineContext',
callback: runLineContext,
},
/** 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;
{
name: 'mind-reader.runCursorContext',
callback: runCursorContext
}
]
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);
}
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 {
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");
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
const tabFmt: pl.TabInfo = {
size: typeof editor.options.tabSize === 'number'? editor.options.tabSize: 4,
hard: !editor.options.insertSpaces
};
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
{
// Grab tab format from open document
let tabFmt = {
size: editor.options.tabSize as number,
hard: !editor.options.insertSpaces
};
let i = pl.Lexer.getIndent(textLine.text, tabFmt);
vscode.window.showInformationMessage("Line Number " + lineNum.toString() + " Indentation " + i.toString());
else {
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
}
}
else{
vscode.window.showErrorMessage('No document currently active');
}
}
function runLineContext(): void {
let editor = vscode.window.activeTextEditor;
if (editor){
// current text and line number
let editorText = editor.document.getText();
let line = editor.selection.active.line;
const editor: TextEditor | undefined = window.activeTextEditor;
// get tab info settings
let size = parseInt(editor.options.tabSize as string);
let hard = !editor.options.insertSpaces;
if (editor) {
// current text and line number
const editorText: string = editor.document.getText();
const line : number = editor.selection.active.line;
// get tab info settings
const size : number = typeof editor.options.tabSize === 'number'? editor.options.tabSize: 4;
const hard : boolean = !editor.options.insertSpaces;
// initialize parser
const parser : pl.Parser = new pl.Parser(editorText, {
size,
hard
});
// initialize parser
let parser = new pl.Parser(editorText, {size, hard});
parser.parse();
parser.parse();
const context: pl.LexNode[] = parser.context(line);
// build text
const contentString: string = createContextString(context, line);
let context = parser.context(line);
// build text
let contentString = createContextString(context, line);
vscode.window.showInformationMessage(contentString);
} else {
vscode.window.showErrorMessage('No document currently active');
}
window.showInformationMessage(contentString);
}
else {
window.showErrorMessage('No document currently active');
}
}
function createContextString(context: pl.LexNode[], line: number): string {
if (context.length < 1) {
throw new Error('Cannot create context string for empty context');
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();
let tokenTypeString: string = `${context[0].token.type.toString()}`;
contextString += `: ${tokenTypeString !== pl.PylexSymbol.STATEMENT?tokenTypeString:""
} ${context[0].token.attr.toString()}`;
}
for (let i = 1; i < context.length; i++) {
let node = context[i];
if (node.label === 'root') {
// root
contextString += ' in the Document Root';
continue;
}
if (node.token!.type !== pl.PylexSymbol.EMPTY &&
node.token!.type !== pl.PylexSymbol.INDENT) {
contextString += ' inside ' + node.token!.type.toString();
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;
if (!editor) {
vscode.window.showErrorMessage('RunCursorContext: No Active Editor');
return;
}
const editor: TextEditor | undefined = window.activeTextEditor;
const cursorPos: vscode.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;
// clamp cursor start/end to new range
let col = cursorPos.character; // effective column of the cursor position
if (col < leadingWS) {
// move effective start to first non-whitespace character in the line
col = leadingWS;
} 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}[] = [];
while (pos < maxPos && trimmedText.length > 0) {
let word = trimmedText.replace(/ .*/, '');
spaceWords.push({word, start: pos, end: pos+word.length});
// remove processed word from trimmed text
const oldText = trimmedText;
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++) {
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++) {
contextString += spaceWords[i].word + ' ';
}
// output cursor context string
vscode.window.showInformationMessage(contextString);
return;
if (!editor) {
window.showErrorMessage('RunCursorContext: No Active Editor');
return;
}
}
}
const cursorPos : Position = editor.selection.active;
const text : string = editor.document.lineAt(cursorPos).text;
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 : 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) {
// 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
const spaceWords: any[] = [];
while (pos < maxPos && trimmedText.length > 0) {
const word: string = trimmedText.replace(/ .*/, '');
spaceWords.push({
word,
start: pos,
end: pos + word.length
});
// remove processed word from trimmed text
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;
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: string = '';
for (let i: number = contextStart; i < contextEnd; i++) {
contextString += spaceWords[i].word + ' ';
}
// output cursor context string
window.showInformationMessage(contextString);
return;
}
}
}

31
src/ev3Manager.ts Normal file
View 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;
}
});
}
}

View File

@ -1,49 +1,47 @@
import * as vscode from 'vscode';
import * as pl from './pylex';
import * as vscode from "vscode";
import * as pl from "./pylex";
import CommandNodeProvider from "./commandNodeProvider";
import Logger from "./log";
import { lineHighlighter } from "./lineHighlighter";
import {
accessCommands,
hubCommands,
navCommands,
textCommands
} from './commands';
import CommandNodeProvider from './commandNodeProvider';
import Logger from './log';
import { accessCommands, hubCommands, navCommands, textCommands } from "./commands";
// Output Logger
const product: string = vscode.workspace.getConfiguration('mindReader').get('productType')!;
const outputChannel = vscode.window.createOutputChannel(product + " Output");
export const logger = new Logger(outputChannel);
const product: string = vscode.workspace.getConfiguration("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() {}

View File

@ -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);
}
}
}

312
src/lineHighlighter.ts Normal file
View File

@ -0,0 +1,312 @@
/**
* ?
* ?
* ?
* ?
* ?
* ?
* ! 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.textDecoration" : "none",
* "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();
}
}

View File

@ -1,9 +1,9 @@
import { LineToken } from '.';
import { LineToken } from '.';
import { Symbol, EOFTOKEN, TabInfo } from './token';
type Rule = {
pattern: RegExp,
type: Symbol,
pattern: RegExp,
type : Symbol,
};
/**
@ -11,205 +11,248 @@ type Rule = {
* The first item is a recognition pattern, used to recognize the token
* the second item is the token type
*/
const rules: Rule[] = [
{
pattern: /^\s*def\s+(?<attr>[a-zA-Z_][a-zA-Z0-9_]*)\(/,
type: Symbol.FUNCTION
},
{
pattern: /^\s*class\s+(?<attr>[a-zA-Z_][a-zA-Z0-9_]*)/,
type: Symbol.CLASS
},
{
pattern: /^\s*if\s+(?<attr>[^:]+):\s*/,
type: Symbol.IF
},
{
pattern: /^\s*elif\s+(?<attr>[^:]+):\s*$/,
type: Symbol.ELIF
},
{
pattern: /^\s*else\s*:/,
type: Symbol.ELSE
},
{
pattern: /^\s*for\s+(?<attr>[^:]+):\s*$/,
type: Symbol.FOR
},
{
pattern: /^\s*while\s+(?<attr>[^:]+):\s*$/,
type: Symbol.WHILE
},
{
pattern: /^\s*try\s*:/,
type: Symbol.TRY
},
{
pattern: /^\s*except(\s*(?<attr>[^:]+))?:\s*$/,
type: Symbol.EXCEPT
},
{
pattern: /^\s*finally\s*:\s*$/,
type: Symbol.FINALLY
},
{
pattern: /^\s*with\s+(?<attr>[^:]+):\s*$/,
type: Symbol.WITH
},
const rules: Rule[] = [{
pattern: /^\s*def\s+(?<attr>[a-zA-Z_][a-zA-Z0-9_]*)\(/,
type: Symbol.FUNCTION
},
{
pattern: /^\s*class\s+(?<attr>[a-zA-Z_][a-zA-Z0-9_]*)/,
type: Symbol.CLASS
},
{
pattern: /^\s*if\s+(?<attr>[^:]+):\s*/,
type: Symbol.IF
},
{
pattern: /^\s*elif\s+(?<attr>[^:]+):\s*$/,
type: Symbol.ELIF
},
{
pattern: /^\s*else\s*:/,
type: Symbol.ELSE
},
{
pattern: /^\s*for\s+(?<attr>[^:]+):\s*$/,
type: Symbol.FOR
},
{
pattern: /^\s*while\s+(?<attr>[^:]+):\s*$/,
type: Symbol.WHILE
},
{
pattern: /^\s*try\s*:/,
type: Symbol.TRY
},
{
pattern: /^\s*except(\s*(?<attr>[^:]+))?:\s*$/,
type: Symbol.EXCEPT
},
{
pattern: /^\s*finally\s*:\s*$/,
type: Symbol.FINALLY
},
{
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
}
];
/**
* Line-By-Line Lexer
*/
export default class Lexer {
private textLines: string[] = []; // array of text lines
private pos: number = 0;
private _currToken: LineToken = EOFTOKEN;
private textLines : string[] = []; // array of text lines
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!);
}
/**
* @param `text` The text to lex.
* @param `tabFmt` A tab information descriptor
*/
constructor(text ? : string, private tabFmt ? : TabInfo) {
// default is 4 wide expanded tabs
this.tabFmt = {
...{
size: 4,
hard: false
},
...tabFmt
};
return indent;
}
/**
* @param `text` The text to lex.
* @param `tabFmt` A tab information descriptor
*/
constructor(text?: string, private tabFmt?: TabInfo) {
// default is 4 wide expanded tabs
this.tabFmt = {
...{size: 4, hard: false},
...tabFmt
};
if (text) {
// normalize linefeeds
text = text.replace('\r\n', '\n');
}
this.restart(text);
}
/**
* Restart lexer with new text.
*
* @param `text` The new text to lex.
*/
restart(text?: string): void {
this.pos = 0;
this._currToken = EOFTOKEN; // if no input, already on EOFTOKEN
if (text) {
this.textLines = text.split('\n');
this.next(); // advance to the first token
}
}
/**
* @return the current {@link LineToken}.
*/
currToken(): LineToken { return this._currToken; }
/**
* Advance the position in the token stream.
*
* @return The new current token, after advancing
*/
next(): LineToken {
if (this._currToken === EOFTOKEN && this.pos > this.textLines.length) {
throw new Error('Cannot advance past end');
}
// 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!);
let token: LineToken;
for (var r of rules) {
// Does line match pattern?
let match: RegExpMatchArray | null = line.match(r.pattern);
if (match) {
// Yes...
if (match.groups) {
token = new LineToken(r.type, this.pos, indent, match.groups["attr"]);
} else {
token = new LineToken(r.type, this.pos, indent);
}
this._currToken = token;
this.pos++;
return this.currToken();
if (text) {
// normalize line feeds
text = text.replace('\r\n', '\n');
}
}
// 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);
}
this._currToken = token;
this.pos++;
return this.currToken();
this.restart(text);
}
// Didn't return, must be EOF
this._currToken = EOFTOKEN;
this.pos++;
return this.currToken();
}
/**
* Move backwards in the token stream
*
* @param `n` The number of positions to retract.
* @return The new current token after retracting.
*/
retract(n: number = 1): LineToken {
if (this.pos - 1 - n < 0) {
// -1 because this.pos is currently on the next token
throw new RangeError('Cannot retract past start');
/**
* Restart lexer with new text.
*
* @param `text` The new text to lex.
*/
restart(text ? : string): void {
this.pos = 0;
this._currToken = EOFTOKEN; // if no input, already on EOFTOKEN
if (text) {
this.textLines = text.split('\n');
this.next(); // advance to the first token
}
}
if (n <= 0) {
throw new RangeError('Retract distance must be positive');
/**
* @return the current {@link LineToken}.
*/
currToken(): LineToken {
return this._currToken;
}
if (this.pos - n === 0) {
// just restart
this.pos = 0;
return this.next();
/**
* Advance the position in the token stream.
*
* @return The new current token, after advancing
*/
next(): LineToken {
if (this._currToken === EOFTOKEN && this.pos > this.textLines.length) {
throw new Error('Cannot advance past end');
}
// Until a LineToken is found, or EOF
while (this.pos < this.textLines.length) {
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?
const match: RegExpMatchArray | null = line.match(r.pattern);
if (match) {
// Yes...
if (match.groups) {
token = new LineToken(r.type, this.pos, indent, match.groups["attr"]);
} else {
token = new LineToken(r.type, this.pos, indent);
}
this._currToken = token;
this.pos++;
return this.currToken();
}
}
// No rules matched
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();
}
let c = n + 1;
while (c > 0) {
this.pos--;
while (/^\s*(#.*)?$/.test(this.textLines[this.pos])) {
// Skip empty lines
this.pos--;
}
c--;
/**
* Move backwards in the token stream
*
* @param `n` The number of positions to retract.
* @return The new current token after retracting.
*/
retract(n: number = 1): LineToken {
if (this.pos - 1 - n < 0) {
// -1 because this.pos is currently on the next token
throw new RangeError('Cannot retract past start');
}
if (n <= 0) {
throw new RangeError('Retract distance must be positive');
}
if (this.pos - n === 0) {
// just restart
this.pos = 0;
return this.next();
}
let c = n + 1;
while (c > 0) {
this.pos--;
while (/^\s*(#.*)?$/.test(this.textLines[this.pos])) {
// Skip empty lines
this.pos--;
}
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;
}
return this.next();
}
}

View File

@ -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(

View File

@ -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}`;
}
}

View File

@ -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,11 +51,14 @@ 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});
assert.strictEqual(l.currToken().indentLevel, i+1);
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'));

View File

@ -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);
});

View File

@ -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,
new LexNode('else',
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,
new LexNode('else',
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...")')
])
])
}
];

View File

@ -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
};