From dd9b9da9082c0b7526f3bd475cc14bdb1762affc Mon Sep 17 00:00:00 2001 From: wiggin77 Date: Wed, 11 Jan 2017 20:57:22 -0500 Subject: [PATCH] Updated README --- .vscode/launch.json | 1 + README.md | 92 +++++++++++++++++--------------- TODO.md | 11 ++-- package.json | 2 +- src/wiggin/codedox/CodeDox.hx | 59 ++++++++++---------- src/wiggin/codedox/Commenter.hx | 16 +++--- src/wiggin/codedox/FileHeader.hx | 80 +++++++++++++++++---------- src/wiggin/codedox/Setup.hx | 11 ++-- test/.vscode/settings.json | 15 +----- test/Test.hx | 5 +- 10 files changed, 151 insertions(+), 141 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e31ccb2..d06e7c0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,6 +15,7 @@ "${workspaceRoot}/out/**/*.js" ], "preLaunchTask": "haxe", + "internalConsoleOptions": "openOnSessionStart", "smartStep": true } ] diff --git a/README.md b/README.md index 30f891a..38f26b6 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,17 @@ This is an extension for [Visual Studio Code](https://code.visualstudio.com) that helps developers document their [Haxe](http://haxe.org/) code. JSDoc style comments can be inserted including automatic generation of `@param` and `@return` tags. File headers can be inserted with customizable -copyright and license comments. +copyright and license comments, or you can choose from a variety of built-in license texts. This extension is best used as a companion to [vshaxe](https://marketplace.visualstudio.com/items?itemName=nadako.vshaxe) which provides Haxe support for Visual Studio Code. ## Usage -1. Add Codedox settings to your workspace or user configuration. Cut and paste from sample [here](./sample.codedox.json). -2. Customize your copyright and license text. Sample MIT license included below. -3. Type `/*` at top of file to insert a file header. -4. Position cursor before a function declaration and type `/**` to insert a JSDoc-style comment. +1. Type `/*` at top of file to insert a file header. + - if no file header template has been configured then a simple setup wizard will ask a few questions and save the configuration +2. Position cursor before a function declaration and type `/**` to insert a JSDoc-style comment. +3. Position cursor before a variable or class declaration and type `/**` to get an empty JSDoc-style comment, then press `enter` immediately to get a multiline comment. File header and JSDoc-style comments can also be inserted using commands. Invoke the commands using `F1` or `Ctrl-Shift-P`/`Cmd-Shift-P` and typing `Codedox: Insert ...` @@ -30,16 +30,37 @@ typing `Codedox: Insert ...` ### Insert file header ![Field completion](images/fileheader.gif) -## Configuration +## Setup 'Wizard' -Codedox supports the following settings. These can be cut and pasted into user or workspace settings file (`.vscode/settings.json`) -and customized as needed. The example below includes an MIT license: +A basic configuration can be created using the simple setup 'wizard'. This is triggered when typing `/*` at the top of a file for the first time, +or by running the setup command using `F1` or `Ctrl-Shift-P`/`Cmd-Shift-P` and typing `Codedox: Setup ...`. + +The wizard will ask: +1. Where you want the configuration saved (user or workspace) +2. Which of the built-in license templates you want to use (if any) + - GNU Affero General Public License + - Apache License, Version 2.0 + - GNU General Public License, Version 3.0 + - MIT License + - Mozilla Public License, Version 2.0 + - Simple copyright +3. A company/author name to include in your copyright. + +## Advanced Configuration + +Most Codedox settings are optional, and all required settings can be generated by the setup wizard. If you want use a built-in license template or simple +copyright then just run the setup wizard and skip this section. + +If you want to create a custom license/copyright template or want to change how the comments look, then you can cut and paste the following into your +user or workspace settings file (`.vscode/settings.json`) and customize as needed. A list of built-in parameters that can be used in your custom templates +is also listed below. ```js { "codedox": { - "autoInsert": true, // Enables insertion trigged by keystrokes - "autoPrefixOnEnter": true, // Enables 'on enter' rules + "autoInsert": true, // Enables insertion of function comments trigged by keystrokes + "autoInsertHeader": true, // Enables insertion of file header triggered by keystrokes + "autoPrefixOnEnter": true, // Enables 'on enter' rules "commentprefix": "* ", "commentbegin": "/**", "commentend": "*/", @@ -51,32 +72,15 @@ and customized as needed. The example below includes an MIT license: "params": { "*": { "company": "My Company", - "license_mit": [ - "${headerprefix} Copyright (c) ${year} ${company}", - "${headerprefix}", - "${headerprefix} Permission is hereby granted, free of charge, to any person obtaining a copy of", - "${headerprefix} this software and associated documentation files (the \"Software\"), to deal in", - "${headerprefix} the Software without restriction, including without limitation the rights to use,", - "${headerprefix} copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the", - "${headerprefix} Software, and to permit persons to whom the Software is furnished to do so,", - "${headerprefix} subject to the following conditions:", - "${headerprefix}", - "${headerprefix} The above copyright notice and this permission notice shall be included in all", - "${headerprefix} copies or substantial portions of the Software.", - "${headerprefix}", - "${headerprefix} THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", - "${headerprefix} IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", - "${headerprefix} FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", - "${headerprefix} COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN", - "${headerprefix} AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH", - "${headerprefix} THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." - ] + "author": "Wiggin" } }, "templates": { "*": [ "${headerbegin}", - "${license_mit}", + "${headerprefix} Copyright (c) ${year} ${company}", + "${headerprefix}", + "${headerprefix} Author: ${author}", "${headerend}" ] } @@ -84,21 +88,25 @@ and customized as needed. The example below includes an MIT license: } } ``` -Additional built-in parameters: +Built-in parameters: Param | Result --------------|--------------------- -${year} | 2017 -${month} | 1 -${day} | 2 -${timestamp} | 2017-01-02 15:17:40 -${time24h} | 15:17:40 -${date} | 2017-01-02 -${time} | 3:17:40 PM - +${year} | 2017 +${month} | 1 +${day} | 2 +${timestamp} | 2017-01-02 15:17:40 +${time24h} | 15:17:40 +${date} | 2017-01-02 +${time} | 3:17:40 PM +${license_agpl_3_0} | GNU Affero General Public License +${license_apache_2_0} | Apache License, Version 2.0 +${license_gpl_3_0} | GNU General Public License, Version 3.0 +${license_mit} | MIT License +${license_mozillapl_2_0} | Mozilla Public License, Version 2.0 +${license_none} | Simple copyright ## Notes * If you do not want an asterisk preceding each line of a comment, replace the `commentprefix` property with `" "`. * If you prefer only one space before each line of a comment, replace `commentprefix` with `"* "`. -* Feature requests. comments, etc, welcome. - +* Feature requests. comments, etc, are welcome. diff --git a/TODO.md b/TODO.md index f4b24e2..4a2bb4f 100644 --- a/TODO.md +++ b/TODO.md @@ -6,13 +6,12 @@ - (FIXED) Setup saving to USER overwrites existing params in USER; same for WORKSPACE. - (DONE) When populating template, merge params from "*" and "haxe" such that haxe overrides "*". - (DONE) Handle /** better for non-function comment --> end up with something like "\** | *\" - -- handle */ and **/ auto close brackets; Haxe uses **/ for some reason +- (FIXED) After setup wizard trigger by /* the re-running of cmd insert_file_header fails. + - only when writing to WORKSPACE settings; the new data is not available + until approx 1 sec delay (machine specific?), even though we wait for + the promise to resolve. +- (DONE) Handle */ and **/ auto close brackets; Haxe uses **/ for some reason - When preceeding a class declaration, create empty multi-line JSDoc. -- after setup wizard trigger by /* the re-running of cmd insert_file_header fails. - - only when writing to WORKSPACE settings; the new data is not available - until approx 1 sec delay (machine specific?), even though we wait for - the promise to resolve. diff --git a/package.json b/package.json index 75ac4f0..cc1c641 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "default": true }, "neverAskTemplate": { - "description": "If true then never asks to select default template", + "description": "If true then never asks to select default template via setup wizard", "type": "boolean", "default": false }, diff --git a/src/wiggin/codedox/CodeDox.hx b/src/wiggin/codedox/CodeDox.hx index 8dde528..3af5624 100644 --- a/src/wiggin/codedox/CodeDox.hx +++ b/src/wiggin/codedox/CodeDox.hx @@ -38,8 +38,8 @@ using StringTools; typedef Settings = {autoInsert:Bool, autoInsertHeader:Bool, strCommentBegin:String, strCommentEnd:String, strCommentPrefix:String, strCommentDescription:String, strCommentTrigger:String, - strAutoClosingClose:String, strHeaderBegin:String, strHeaderEnd:String, strHeaderPrefix:String, - strHeaderTrigger:String, } + strAutoClosingClose:String, strAutoClosingCloseAlt:String, strHeaderBegin:String, + strHeaderEnd:String, strHeaderPrefix:String, strHeaderTrigger:String, } /** * Main extension class. @@ -88,13 +88,6 @@ class CodeDox m_commenter = null; s_extPath = context.extensionPath; - // Check for first run. - var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(EXTENSION_NAME); - if(config.get("firstrun", -1) == -1) - { - initFirstRun(config); - } - context.subscriptions.push(Vscode.workspace.onDidChangeConfiguration(function(Void){s_settings=null;})); context.subscriptions.push(Vscode.workspace.onDidChangeTextDocument(onTextChange)); @@ -103,6 +96,7 @@ class CodeDox registerTextEditorCommand(context, CMD_INSERT_COMMENT, insertComment); // Add onEnter rules. + var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(EXTENSION_NAME); var bAutoPrefixOnEnter = config.get("autoPrefixOnEnter", true); var strCommentPrefix = config.get("commentprefix", "* "); if(bAutoPrefixOnEnter) @@ -310,12 +304,15 @@ class CodeDox } } else if(settings.autoInsert && strChangeText == settings.strCommentTrigger || - strChangeText == settings.strCommentTrigger + settings.strAutoClosingClose) + strChangeText == settings.strCommentTrigger + settings.strAutoClosingClose || + strChangeText == settings.strCommentTrigger + settings.strAutoClosingCloseAlt) { // A function comment trigger was typed. var line = doc.lineAt(change.range.start.line); var strCheck = StringUtil.trim(line.text); - if(strCheck == settings.strCommentBegin || strCheck == settings.strCommentBegin + settings.strAutoClosingClose) + if(strCheck == settings.strCommentBegin || + strCheck == settings.strCommentBegin + settings.strAutoClosingClose || + strCheck == settings.strCommentBegin + settings.strAutoClosingCloseAlt) { doCommentInsert(line, editor); } @@ -385,14 +382,25 @@ class CodeDox { Vscode.window.showErrorMessage(strMsg + strExp); - trace(strMsg + strExp); + log(strMsg + strExp); if(stack != null) { - trace(haxe.CallStack.toString(stack)); + log(haxe.CallStack.toString(stack)); } } } + /** + * Logs message to console via trace. + * @param msg - message to output + */ + public static function log(msg:Dynamic, ?pos:haxe.PosInfos) : Void + { + #if debug + trace(Std.string(msg), pos); + #end + } + /** * Returns true if the language id is supported by this extension. * @param strLangId - the language id to check @@ -420,7 +428,8 @@ class CodeDox var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(EXTENSION_NAME); var strCommentBegin = config.get("commentbegin", "/**"); var strHeaderBegin = config.get("headerbegin", "/*"); - var strAutoClose = getAutoClosingClose(strCommentBegin); + var strAutoClose = getAutoClosingClose(strCommentBegin, false); + var strAutoCloseAlt = getAutoClosingClose(strCommentBegin, true); s_settings = { autoInsert: config.get("autoInsert", true), @@ -431,6 +440,7 @@ class CodeDox strCommentDescription: config.get("commentdescription", "[Description]"), strCommentTrigger: StringUtil.right(strCommentBegin, 1), strAutoClosingClose: (strAutoClose != null) ? strAutoClose : "", + strAutoClosingCloseAlt: (strAutoCloseAlt != null) ? strAutoCloseAlt : "", strHeaderBegin: config.get("headerbegin", "/*"), strHeaderEnd: config.get("headerend", "*/"), strHeaderPrefix: config.get("headerprefix", " *"), @@ -454,38 +464,23 @@ class CodeDox * e.g. "\**" is usually closed with "*\". * * @param strAutoClosingOpen - the opening string of an autoclosing pair + * @param bAlt - true if the alternative close pair is to be returned * @return String or null */ - private static function getAutoClosingClose(strAutoClosingOpen:String) : Null + private static function getAutoClosingClose(strAutoClosingOpen:String, ?bAlt = false) : Null { // Dammit. Vscode won't let me lookup the LanguageConfiguration settings. // Maybe this will be added in the future: https://github.com/Microsoft/vscode/issues/2871 - //var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(); - //var arr = config.get("haxe.configuration.autoClosingPairs", ["empty"]); - // We'll have to hack something for now... return switch(strAutoClosingOpen) { // For some reason the Haxe extension configures vscode to autoclose with double asterisk. - case "/**": "**/"; + case "/**": (bAlt) ? "*/" : "**/"; // Just reverse the open until we can read the real value?? default: StringUtil.reverse(strAutoClosingOpen); } } - /** - * Called when the extension is run for the first time. Here we persist a default config - * so the user doesn't have to. - * e.g. "\**" is usually closed with "*\". - * - * @param strAutoClosingOpen - the opening string of an autoclosing pair - * @return String or null - */ - private static function initFirstRun(config:WorkspaceConfiguration) : Void - { - - } - } // end of CodeDox class \ No newline at end of file diff --git a/src/wiggin/codedox/Commenter.hx b/src/wiggin/codedox/Commenter.hx index 4be125e..424faff 100644 --- a/src/wiggin/codedox/Commenter.hx +++ b/src/wiggin/codedox/Commenter.hx @@ -66,9 +66,7 @@ class Commenter } else { - #if debug - trace("insertComment aborted: no function to parse"); - #end + CodeDox.log("insertComment aborted: no function to parse"); } } @@ -116,12 +114,12 @@ class Commenter var arrParams = parseParams(strParams, doc.languageId); #if debug - trace("*****"); - trace('Indent Len=' + strIndent.length); - trace('Indent=' + StringUtil.escapeWhitespace(strIndent)); - trace('params=${arrParams}'); - trace('return=${strReturnType}'); - trace("*****"); + CodeDox.log("*****"); + CodeDox.log('Indent Len=' + strIndent.length); + CodeDox.log('Indent=' + StringUtil.escapeWhitespace(strIndent)); + CodeDox.log('params=${arrParams}'); + CodeDox.log('return=${strReturnType}'); + CodeDox.log("*****"); #end strComment = composeComment(strIndent, arrParams, strReturnType); diff --git a/src/wiggin/codedox/FileHeader.hx b/src/wiggin/codedox/FileHeader.hx index 3c6717b..1f402d3 100644 --- a/src/wiggin/codedox/FileHeader.hx +++ b/src/wiggin/codedox/FileHeader.hx @@ -34,6 +34,8 @@ import wiggin.util.RegExUtil; import wiggin.util.ConfigUtil; import wiggin.util.StructUtil; +typedef SetupCompleteContext = {count:Int, strLang:String} + /** * Implements command for inserting file header at top of files. */ @@ -85,28 +87,21 @@ class FileHeader */ private function getFileHeader(strLang:String) : String { - var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(); - - var strTemplate = getTemplate(config, strLang); - strTemplate = populateTemplate(config, strTemplate, strLang); + var strTemplate = getTemplate(strLang); + strTemplate = populateTemplate(strTemplate, strLang); return strTemplate + "\n"; } /** * Fetches the template associated with the language id or the default. * - * @param config - the `WorkspaceConfiguration` containing settings * @param strLang - the language id for the current editor document. e.g. "haxe" * @return String - the formatted template ready to be inserted into document */ - private function getTemplate(config:WorkspaceConfiguration, strLang:String) : String + private function getTemplate(strLang:String) : String { - var template:Array = config.get(TEMPLATES + "." + strLang, null); - if(template == null) - { - template = config.get(TEMPLATES + ".*", null); - } - + var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(); + var template:Array = getTemplateConfig(strLang); if(template == null || template.length == 0) { if(config.get(CodeDox.EXTENSION_NAME + ".neverAskTemplate", false)) @@ -121,11 +116,12 @@ class FileHeader Vscode.window.showErrorMessage(msg, item1, item2, item3).then(function(item:MessageItem){ if(item.title == item1.title) { - Vscode.commands.executeCommand(CodeDox.CMD_SETUP).then(onSetupComplete); + var ctx:SetupCompleteContext = {count:0, strLang:strLang}; + Vscode.commands.executeCommand(CodeDox.CMD_SETUP).then(function(bResult){onSetupComplete(bResult,ctx);}); } else if(item.title == item3.title) { - setNeverAsk(config); + setNeverAsk(); } }); template = [""]; // This will erase what the user typed. @@ -137,13 +133,46 @@ class FileHeader * Called after the Setup wizard was triggered during file header insertion. * @param bResult - true if the wizard completed successfully */ - private function onSetupComplete(bResult:Bool) : Void + private function onSetupComplete(bResult:Bool, cxt:SetupCompleteContext) : Void { if(bResult) { - // Now that the setup wizard has created a minimal config, re-run the insert header command. - js.Node.setTimeout(function(){Vscode.commands.executeCommand(CodeDox.CMD_INSERT_FILE_HEADER);}, 1000); + // Work-around: despite waiting for the Promise to resolve, sometimes the workspace config update + // is not available for reading right away. The latency seems to vary based on machine + // and load? Here we'll try a few times then give up. + var template = getTemplateConfig(cxt.strLang); + if(template == null || template.length == 0) + { + if(cxt.count <= 10) + { + CodeDox.log("template still empty. Trying again, count=" + cxt.count); + cxt.count++; + js.Node.setTimeout(function(){onSetupComplete(bResult,cxt);}, 250); + } + } + else + { + // Now that the setup wizard has created a minimal config, re-run the insert header command. + js.Node.setTimeout(function(){Vscode.commands.executeCommand(CodeDox.CMD_INSERT_FILE_HEADER);}, 10); + } + } + } + + /** + * Fetches the raw template data associated with the language id or the default. + * + * @param strLang - the language id for the current editor document. e.g. "haxe" + * @return Array - the raw template data + */ + private function getTemplateConfig(strLang:String) : Array + { + var config = Vscode.workspace.getConfiguration(); + var template:Array = config.get(TEMPLATES + "." + strLang, null); + if(template == null) + { + template = config.get(TEMPLATES + ".*", null); } + return template; } /** @@ -155,8 +184,9 @@ class FileHeader * @param strLang - the language id for the current editor document. e.g. "haxe" * @return String - the populated template */ - private function populateTemplate(config:WorkspaceConfiguration, strTemplate:String, strLang:String) : String + private function populateTemplate(strTemplate:String, strLang:String) : String { + var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(); var paramsStar:Dynamic = config.get(PARAMS + ".*", null); var paramsLang:Dynamic = config.get(PARAMS + "." + strLang, null); var params:Dynamic = StructUtil.mergeStruct(paramsStar, paramsLang); @@ -290,24 +320,20 @@ class FileHeader /** * Updates the user's config so that it will never offer to choose a default template. - * @param config - the `WorkspaceConfiguration` to write to */ - private static function setNeverAsk(config:WorkspaceConfiguration) : Void + private static function setNeverAsk() : Void { + var config:WorkspaceConfiguration = Vscode.workspace.getConfiguration(); var update = {neverAskTemplate:true}; ConfigUtil.update(config, CodeDox.EXTENSION_NAME, update).then( function(Void) { - #if debug - trace(CodeDox.EXTENSION_NAME + ".neverAskTemplate set to true successfully."); - #end + CodeDox.log(CodeDox.EXTENSION_NAME + ".neverAskTemplate set to true successfully."); }, function(result) { - #if debug - trace("Failed to set " + CodeDox.EXTENSION_NAME + ".neverAskTemplate"); - trace(result); - #end + CodeDox.log("Failed to set " + CodeDox.EXTENSION_NAME + ".neverAskTemplate"); + CodeDox.log(result); } ); } diff --git a/src/wiggin/codedox/Setup.hx b/src/wiggin/codedox/Setup.hx index 873a3d6..9d804f6 100644 --- a/src/wiggin/codedox/Setup.hx +++ b/src/wiggin/codedox/Setup.hx @@ -191,18 +191,13 @@ class Setup ConfigUtil.update(config, CodeDox.EXTENSION_NAME, m_transaction.obj, m_transaction.scope).then( function(Void) { - #if debug - trace(CodeDox.EXTENSION_NAME + "Config updated successfully."); - #end - + CodeDox.log(CodeDox.EXTENSION_NAME + "Config updated successfully."); resolve(true); }, function(reason) { - #if debug - trace("Failed to update " + CodeDox.EXTENSION_NAME + " config."); - trace(reason); - #end + CodeDox.log("Failed to update " + CodeDox.EXTENSION_NAME + " config."); + CodeDox.log(reason); var str = (m_transaction.scope == Scope.USER) ? "user settings.json" : "workspace settings.json"; reject('Error updating config. Check for errors in your ${str} and try again.'); diff --git a/test/.vscode/settings.json b/test/.vscode/settings.json index d032289..cfb0380 100644 --- a/test/.vscode/settings.json +++ b/test/.vscode/settings.json @@ -10,17 +10,6 @@ //["build-cpp.hxml"] ], // Codedox settings - "codedox": { - "fileheader": { - "params": { - "*": { - "company": "WS_Company", - "author": "Ws_author" - }, - "haxe": { - "author": "haxe_ws_author" - } - } - } - } + "codedox": { + } } diff --git a/test/Test.hx b/test/Test.hx index bbe18a8..d897326 100644 --- a/test/Test.hx +++ b/test/Test.hx @@ -1,9 +1,8 @@ - package ; -class Test +class Test { - private var m_strToken:String; + private var m_strToken:String; public static function main() {