diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d16692..b9418f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,3 +56,10 @@ ## 2.0.8 - Fixed a bug with FOR/NEXT recognition and spacing (#107) + +## 2.0.9 + +- Fixed a bug with LOOP/REPEAT recognition and spacing (no issue) +- Fixed a bug with formatting for comment lines (#110) +- Added new indentComment setting to control comment indentation (#111) +- Added new customFunctionPath setting to allow users to contribute custom functions/subroutines for IntelliSense and linting (#113) \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index ff5333b..db6f3a5 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,6 +1,6 @@ { "name": "mvbasic", - "version": "2.0.6", + "version": "2.0.9", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -313,4 +313,4 @@ "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" } } -} +} \ No newline at end of file diff --git a/client/package.json b/client/package.json index 26084dc..6226856 100644 --- a/client/package.json +++ b/client/package.json @@ -2,7 +2,7 @@ "name": "mvbasic", "displayName": "MV Basic", "description": "MV Basic", - "version": "2.0.8", + "version": "2.0.9", "publisher": "mvextensions", "license": "MIT", "icon": "../images/mvbasic-logo.png", diff --git a/client/src/extension.ts b/client/src/extension.ts index 14ec135..c14bab4 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -27,6 +27,7 @@ var UseGateway: boolean; var UsingRest: boolean; var margin: number; var indent: number; +var indentComment: string; var formattingEnabled: boolean; var editFiles: any; var customWordColor: any; @@ -85,6 +86,7 @@ export function activate(context: vscode.ExtensionContext) { UsingRest = vscode.workspace.getConfiguration("MVBasic").get("UseRestFS"); margin = vscode.workspace.getConfiguration("MVBasic").get("margin"); indent = vscode.workspace.getConfiguration("MVBasic").get("indent"); + indentComment = vscode.workspace.getConfiguration("MVBasic").get("indentComment"); formattingEnabled = vscode.workspace.getConfiguration("MVBasic").get("formattingEnabled"); editFiles = vscode.workspace.getConfiguration("MVBasic").get("EditFiles"); customWordColor = vscode.workspace.getConfiguration("MVBasic").get("customWordColor"); @@ -390,6 +392,32 @@ export function activate(context: vscode.ExtensionContext) { if (RowLevel[i] === undefined) { continue; } indentation = (RowLevel[i] * indent) + margin + + // Comment indent rules + if (rComment.test(lineText)) { + switch (indentComment) { + case "left": { + // Indent comment to margin position 0 + indentation = 0; + break; + } + case "margin": { + // Indent comment to margin position + indentation = margin; + break; + } + case "code": { + // Indent comment with code + break; + } + default: { + // No change to indent if indentComment = "ignore", + // is missing, or has an invalid value. + continue; + } + } + } + if (new RegExp("(^case\\s)", "i").test(lineText)) { indentation -= indent } diff --git a/doc/Extension Guide.md b/doc/Extension Guide.md index 33a6dc9..e4ab7a5 100644 --- a/doc/Extension Guide.md +++ b/doc/Extension Guide.md @@ -40,6 +40,7 @@ All other trademarks and service marks are property of their respective holders. - [6.5 Internal Subroutine lookup](#65-internal-subroutine-lookup) - [6.6 Compiling and Cataloging your programs](#66-compiling-and-cataloging-your-programs) - [6.7 Formatting Programs](#67-formatting-programs) + - [6.8 Custom functions and subroutines](#68-custom-functions-and-subroutines) - [7. Sample Settings Files](#7-sample-settings-files) - [7.1 Universe](#71-universe) - [7.2 Unidata](#72-unidata) @@ -240,9 +241,9 @@ Content-Type: application/json ### 5.2 Option 2 - AccuTerm -To use AccuTerm to connect the MV Basic extension to your MV server, you must be running AccuTerm 7.1 or above (with [this add-on](https://zdownload.blob.core.windows.net/accuterm/Miscellaneous/Windows/x86/1.0.5.0/accuterm-vscode-connector.exe)) or AccuTerm [8.0.1020](https://zdownload.blob.core.windows.net/accuterm/Standard/Windows/x86/8.0.1020.0/atwin_8.0.1020.exe) or above (no add-on required). +To use AccuTerm to connect the MV Basic extension to your MV server, you must be running AccuTerm 7.1 or above (with [this add-on](https://zdownload.blob.core.windows.net/accuterm/Miscellaneous/Windows/x86/1.0.6.0/accuterm-vscode-connector.exe)) or AccuTerm [8.0.1020](https://zdownload.blob.core.windows.net/accuterm/Standard/Windows/x86/8.0.1020.0/atwin_8.0.1020.exe) or above (no add-on required). -The latest version of the AccuTerm host programs should be used with this connector (8.0.7). You can verify your version by typing FTABOUT at a command prompt (TCL) in the ACCUTERM account. You can download version 8.0.7 with [this link](https://zdownload.blob.core.windows.net/accuterm/Host-Programs/Windows/x86/8.0.7.0/pickbp.exe). +The latest version of the AccuTerm host programs should be used with this connector (8.0.7). You can verify your version by typing FTABOUT at a command prompt (TCL) in the ACCUTERM account. You can download version 8.0.10 with [this link](https://zdownload.blob.core.windows.net/accuterm/Host-Programs/Windows/x86/8.0.10.0/pickbp.exe). *Note: the 8.0.1020 release of AccuTerm 8 **does not** include the latest host programs. You should update the host programs after installing 8.0.1020. See above.* @@ -374,6 +375,39 @@ After the option is selected, results are displayed in the `MV Basic` Output win **Right clicking** and selecting `Format Document`, will format your BASIC program. The formatting is based on the 2 settings, `MVBasic.indent` and `MVBasic.margin` that have default values of 3 and 5. +### 6.8 Custom functions and subroutines + +This allows you to autocomplete and document your popular functions and subroutines. + +This is a sample of the autocompleted function that is also displaying the documentation on hover: +![Find References](screenshots/sampleFunctions.png) + +This is a sample of the json file that you use to document the functions and subroutines: + +``` json +{ + "Language": { + "Type": "customFunctionPath", + "functions": [ + { + "key": "SampleFunctionName", + "insertText":"SampleFunctionName('var1')", + "kind": 2, + "detail": "function description that will display in the hover", + "documentation": "function documentaion that will display in the hover\r\nThis is line 2" + } + ] + } +} +``` + +> Note, the `kind` property should map to the [CompletionItemKind](https://code.visualstudio.com/api/references/vscode-api#CompletionItemKind) enumerator from the VS Code api. Typically you will likely set this to `2` to classify items as a _function_ definition. + +This is the MVBasic extension setting that points to the above json file: +| Setting | Value | Description | +| -------------------------- | ---------------------------------- | ----------------------------------------------------------------- | +| MVBasic.customFunctionPath | c:\users\user\customFunctions.json | Path to a file that contains key value pairs for custom functions | + [(top)](#table-of-contents) ## 7. Sample Settings Files diff --git a/doc/screenshots/sampleFunctions.png b/doc/screenshots/sampleFunctions.png new file mode 100644 index 0000000..3a7393a Binary files /dev/null and b/doc/screenshots/sampleFunctions.png differ diff --git a/package-lock.json b/package-lock.json index ad7980f..1c870ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "mvbasic", - "version": "2.0.6", + "version": "2.0.9", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1167,9 +1167,9 @@ } }, "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -4579,4 +4579,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index a1213bb..e8c3e47 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "mvbasic", "displayName": "MV Basic", "description": "MV Basic", - "version": "2.0.8", + "version": "2.0.9", "publisher": "mvextensions", "license": "MIT", "icon": "images/mvbasic-logo.png", @@ -139,12 +139,23 @@ "type": "string", "description": "Path to a file that contains key value pairs for custom words" }, + "MVBasic.customFunctionPath": { + "scope": "resource", + "type": "string", + "description": "Path to a file that contains key value pairs for custom functions" + }, "MVBasic.indent": { "scope": "resource", "type": "number", "default": 3, "description": "The number of characters to use when indenting code blocks." }, + "MVBasic.indentComment": { + "scope": "resource", + "type": "string", + "default": "ignore", + "description": "Indentation of comment lines. Set to: left, margin, code, or ignore." + }, "MVBasic.maxNumberOfProblems": { "scope": "resource", "type": "number", diff --git a/server/package-lock.json b/server/package-lock.json index 8ead303..f223386 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,6 +1,6 @@ { "name": "mvbasic", - "version": "2.0.6", + "version": "2.0.9", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -43,4 +43,4 @@ "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" } } -} +} \ No newline at end of file diff --git a/server/package.json b/server/package.json index 8ac65cd..cf8fed2 100644 --- a/server/package.json +++ b/server/package.json @@ -2,7 +2,7 @@ "name": "mvbasic", "displayName": "MV Basic", "description": "MV Basic", - "version": "2.0.8", + "version": "2.0.9", "publisher": "mvextensions", "license": "MIT", "icon": "../images/mvbasic-logo.png", diff --git a/server/src/server.ts b/server/src/server.ts index 2e3b19b..b5a29fa 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -56,6 +56,7 @@ interface ExampleSettings { ignoreGotoScope: boolean; customWords: string; customWordPath: string; + customFunctionPath: string; languageType: string; trace: any; // expect trace.server is string enum 'off', 'messages', 'verbose' } @@ -69,6 +70,7 @@ interface DocumentLine { let maxNumberOfProblems: number; let customWordList: string; let customWordPath: string; +let customFunctionPath: string; let languageType: string; let logLevel: number; let Intellisense: CompletionItem[] = []; @@ -220,6 +222,22 @@ function loadIntelliSense() { } } + // Load CustomFunction definition + if (customFunctionPath !== "") { + var functionDefinition = fs.readFileSync(customFunctionPath, "utf8"); + var customFunctionList = JSON.parse(functionDefinition); + var functions = customFunctionList.Language.functions; + for (let i = 0; i < functions.length; i++) { + Intellisense.push({ + label: functions[i].key, + insertText: functions[i].insertText, + kind: functions[i].kind, + detail: functions[i].detail, + documentation: functions[i].documentation + }); + } + } + if (logLevel) { connection.console.log( `[Server(${process.pid})] Language definition loaded for ${languageType}` @@ -242,8 +260,8 @@ function validateTextDocument(textDocument: TextDocument): void { let rBlockEnd = new RegExp("(^| )(end|end case|next|next\\s+.+|repeat)$", "i"); let rStartFor = new RegExp("(^| )for\\s+[\\w.]+\\s*=", "i"); let rEndFor = new RegExp("(^| )next($|\\s+.+$)", "i"); - let rStartLoop = new RegExp("(^| )loop\\s*?", "i"); - let rEndLoop = new RegExp("(^| )repeat\\s*$", "i"); + let rStartLoop = new RegExp("(^| )loop( |$)\\s*?", "i"); + let rEndLoop = new RegExp("(^| )repeat( |$)\\s*$", "i"); let rStartCase = new RegExp("(^| )begin case$", "i"); let rEndCase = new RegExp("^\\s*end case$", "i"); let rElseEnd = new RegExp("^\\s*end else$", "i");