├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── img ├── demo.gif └── icon.png ├── language-configuration ├── language-configuration.c.json ├── language-configuration.cpp.json ├── language-configuration.css.json ├── language-configuration.go.json ├── language-configuration.groovy.json ├── language-configuration.less.json ├── language-configuration.objective-c.json ├── language-configuration.php.json ├── language-configuration.rust.json ├── language-configuration.scss.json ├── language-configuration.swift.json ├── multi-line-configuration.json └── single-line-configuration.json ├── package.json ├── src ├── configuration.ts ├── extension.ts └── rules.ts ├── test ├── extension.test.ts └── index.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 11 | "stopOnEntry": false, 12 | "sourceMaps": true, 13 | "outFiles": [ "${workspaceRoot}/out/src/**/*.js" ], 14 | "preLaunchTask": "npm" 15 | }, 16 | { 17 | "name": "Launch Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "runtimeExecutable": "${execPath}", 21 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], 22 | "stopOnEntry": false, 23 | "sourceMaps": true, 24 | "outFiles": [ "${workspaceRoot}/out/test/**/*.js" ], 25 | "preLaunchTask": "npm" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | } 9 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile", "--loglevel", "silent"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isBackground": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | vsc-extension-quickstart.md 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this extension will be documented in this file. 3 | 4 | 5 | 6 | ## [1.0.1] 7 | - Add multi-line support for Rust, Go 8 | - Add single-line support for YAML 9 | 10 | ## [1.0.0] 11 | - Add multi-line comment support for Less, Objective-C/C++, and Swift. 12 | - Add single-line comment blocks for most officially supported languages. See README for more information. 13 | 14 | ## [0.3.2] 15 | - Fix a bug that broke the extension, caused by the previous bugfix. 16 | 17 | ## [0.3.1] 18 | - Fix bug that that caused every language to have single-line block comments. 19 | 20 | ## [0.3.0] 21 | - Add single-line blocks for C/C++ (disabled by default). 22 | - Add comment completion for PHP files. 23 | 24 | ## [0.2.2] 25 | - Add Javadoc-style comments for Groovy files. 26 | 27 | ## [0.2.1] 28 | - Fixed misspelled filename leading to C functionality breaking. 29 | - Change extension description to include support for new languages. 30 | 31 | ## [0.2.0] 32 | - Added block comment completion for CSS/Sass files. 33 | 34 | ## [0.1.0] 35 | - Add QDoc (Qt-style) comment block completion for C and C++. 36 | 37 | ## [0.0.5] 38 | - Fix major typo that caused an asterisk to be inserted following any indented line. 39 | - Changelog now starts with the latest update rather than the oldest. 40 | 41 | ## [0.0.4] 42 | - Fixed an issue that caused asterisk insertion and indentation bugs when indenting using an odd number of spaces. 43 | 44 | ## [0.0.3] 45 | - Changed `galleryBanner.theme`, again. 46 | 47 | ## [0.0.2] 48 | - Changed `galleryBanner.theme`. 49 | 50 | ## [0.0.1] 51 | - Initial release -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Kevin K. Yang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Auto Comment Blocks 2 | 3 | Provides block comment completion for Javadoc-style multi-line comments and single-line comment blocks for most officially supported languages. 4 | 5 | ## MAJOR CHANGES IN 1.0 UPDATE (Please Read) 6 | 7 | A lot has changed in this update. Please open issues for any bugs you encounter. 8 | 9 | ### Single-line Comment Blocks 10 | You can now use single line comment blocks for languages with `//`, `#`, or `;` style single line comments. Press `Shift+Enter` while on a commented line to insert a new commented line with the same level of indentation. See the Settings section for how to change the behavior so that `Enter` inserts a commented line while `Shift+Enter` breaks out of the comment block (this only works correctly for a subset of languages right now). 11 | 12 | The Language Support section shows which languages are supported. See the Settings section for how to add single line comment support to languages that are not officially supported. 13 | 14 | ### Multi-line Comment Blocks 15 | This feature has not changed, but support has now been added for Less, Objective-C/C++, and Swift. 16 | 17 | ## Usage 18 | ![Demo](https://raw.githubusercontent.com/kevinkyang/auto-comment-blocks/master/img/demo.gif) 19 | 20 | ### Javadoc-style comment blocks 21 | Type `/**` to start a block comment, then hit the Enter key, and the extension will close the block. While inside the comment block, the extension will insert an asterisk at the start of every new line, and align the comment, respecting indentation. 22 | 23 | ### QDoc-style (Qt) comment blocks 24 | Use `/*!` in C/C++ files to start a QDoc comment block. 25 | 26 | ### New: "single-line" block comments 27 | You can insert single line comment blocks for languages with `//`, `#`, or `;` style single line comments. Press `Shift+Enter` while on a commented line to insert a new commented line with the same level of indentation. See the Settings section for issues and more options. 28 | 29 | ### Language Support 30 | 31 | | Comment Style | Language Support | 32 | | ------- | ------- | 33 | | `/** */` | C, C++, C#, CSS, Go, Groovy, Java, Less, Objective C/C++, PHP, Sass, Rust, Swift | 34 | | `/*! */` | C, C++ | 35 | | `//`, `///` | C, C++, C#, F#, Go, Groovy, Java, JavaScript, Less, Objective C/C++, PHP, Rust, Sass, Swift, TypeScript | 36 | | `#` | CoffeeScript, Dockerfile, Makefile, Perl, PowerShell, Python, R, Ruby, YAML | 37 | | `;` | Clojure | 38 | 39 | ## Settings 40 | 41 | Reload the extension after changing any settings. 42 | 43 | * `auto-comment-blocks.singleLineBlockOnEnter`: If enabled, pressing `Enter` inserts a new commented line at the same indentation, and pressing `Shift+Enter` breaks the comment block. 44 | + **Caution**: This feature is buggy in many languages (see Issues section), but it seems to work fine for C, C++, Go, Less, PHP, Ruby, and Sass. 45 | * `auto-comment-blocks.disabledLanguages`: Add languageIds here to disable any comment completion for that language. 46 | * `auto-comment-blocks.slashStyleBlocks`: Add languageIds here to enable '//' and '///'-style single line comment blocks for that language. 47 | * `auto-comment-blocks.hashStyleBlocks`: Add languageIds here to enable '#'-style single line comment blocks for that language. 48 | * `auto-comment-blocks.semicolonStyleBlocks`: Add languageIds here to enable ';'-style single line comment blocks for that language. 49 | 50 | ## Issues 51 | 52 | * Single-line blocks using `Enter`: if you enable the `singleLineBlockOnEnter` setting, there are a few things to keep in mind: 53 | + It seems to work find for C, C++, Go, Less, PHP, Ruby, and Sass. 54 | + It doesn't work at all for Python, JavaScript, and TypeScript. 55 | + For every other language, if you press `Tab` immediately after breaking out of a comment block, it will insert a commented line, for some unknown reason. 56 | * Sometimes multi-line completion/aseterisk insertion doesn't work. The reason is still unknown. It may go away if you reload your workspace. 57 | * Currently, VS Code only allows extensions to overwrite, instead of modify, existing language configurations. This means that this extension may clash with another extension that overwrites the same language configurations, causing one or both not to work. In that case, uninstalling this extension is the only option for now. 58 | 59 | Please create an issue in the [repository](https://github.com/kevinkyang/auto-comment-blocks/issues) if you find any bugs, or have questions or feature requests. 60 | 61 | ## Release Notes 62 | 63 | ### 1.0.0 64 | - Add multi-line comment support for Less, Objective-C/C++, and Swift. 65 | - Add single-line comment blocks for most officially supported languages. See README for more information. -------------------------------------------------------------------------------- /img/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevb34ns/auto-comment-blocks/24f8ebc584e3e77d6a116a5a03a80c55008b44a3/img/demo.gif -------------------------------------------------------------------------------- /img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevb34ns/auto-comment-blocks/24f8ebc584e3e77d6a116a5a03a80c55008b44a3/img/icon.png -------------------------------------------------------------------------------- /language-configuration/language-configuration.c.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": ["/*", "*/"] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | { "open": "[", "close": "]" }, 13 | { "open": "{", "close": "}" }, 14 | { "open": "(", "close": ")" }, 15 | { "open": "'", "close": "'", "notIn": ["string", "comment"] }, 16 | { "open": "\"", "close": "\"", "notIn": ["string"] }, 17 | { "open": "/**", "close": " */", "notIn": ["string"] }, 18 | { "open": "/*!", "close": " */", "notIn": ["string"] } 19 | ], 20 | "surroundingPairs": [ 21 | ["{", "}"], 22 | ["[", "]"], 23 | ["(", ")"], 24 | ["\"", "\""], 25 | ["'", "'"] 26 | ] 27 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.cpp.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": ["/*", "*/"] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | { "open": "[", "close": "]" }, 13 | { "open": "{", "close": "}" }, 14 | { "open": "(", "close": ")" }, 15 | { "open": "'", "close": "'", "notIn": ["string", "comment"] }, 16 | { "open": "\"", "close": "\"", "notIn": ["string"] }, 17 | { "open": "/**", "close": " */", "notIn": ["string"] }, 18 | { "open": "/*!", "close": " */", "notIn": ["string"] } 19 | ], 20 | "surroundingPairs": [ 21 | ["{", "}"], 22 | ["[", "]"], 23 | ["(", ")"], 24 | ["\"", "\""], 25 | ["'", "'"] 26 | ] 27 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.css.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "blockComment": ["/*", "*/"] 4 | }, 5 | "brackets": [ 6 | ["{", "}"], 7 | ["[", "]"], 8 | ["(", ")"] 9 | ], 10 | "autoClosingPairs": [ 11 | { "open": "{", "close": "}", "notIn": ["string", "comment"] }, 12 | { "open": "[", "close": "]", "notIn": ["string", "comment"] }, 13 | { "open": "(", "close": ")", "notIn": ["string", "comment"] }, 14 | { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, 15 | { "open": "'", "close": "'", "notIn": ["string", "comment"] }, 16 | { "open": "/**", "close": " */", "notIn": ["string"] } 17 | ], 18 | "surroundingPairs": [ 19 | ["{", "}"], 20 | ["[", "]"], 21 | ["(", ")"], 22 | ["\"", "\""], 23 | ["'", "'"] 24 | ] 25 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.go.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | ["{", "}"], 13 | ["[", "]"], 14 | ["(", ")"], 15 | { "open": "`", "close": "`", "notIn": ["string"]}, 16 | { "open": "\"", "close": "\"", "notIn": ["string"]}, 17 | { "open": "'", "close": "'", "notIn": ["string", "comment"]}, 18 | ["/**", " */"] 19 | ], 20 | "surroundingPairs": [ 21 | ["{", "}"], 22 | ["[", "]"], 23 | ["(", ")"], 24 | ["\"", "\""], 25 | ["'", "'"], 26 | ["`", "`"] 27 | ] 28 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.groovy.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | ["{", "}"], 13 | ["[", "]"], 14 | ["(", ")"], 15 | ["\"", "\""], 16 | ["'", "'"], 17 | ["/**", " */"] 18 | ], 19 | "surroundingPairs": [ 20 | ["{", "}"], 21 | ["[", "]"], 22 | ["(", ")"], 23 | ["\"", "\""], 24 | ["'", "'"] 25 | ] 26 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.less.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "blockComment": ["/*", "*/"], 4 | "lineComment": "//" 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | { "open": "{", "close": "}", "notIn": ["string", "comment"] }, 13 | { "open": "[", "close": "]", "notIn": ["string", "comment"] }, 14 | { "open": "(", "close": ")", "notIn": ["string", "comment"] }, 15 | { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, 16 | { "open": "'", "close": "'", "notIn": ["string", "comment"] }, 17 | { "open": "/**", "close": " */", "notIn":["string", "comment"] } 18 | ], 19 | "surroundingPairs": [ 20 | ["{", "}"], 21 | ["[", "]"], 22 | ["(", ")"], 23 | ["\"", "\""], 24 | ["'", "'"] 25 | ], 26 | "indentationRules": { 27 | "increaseIndentPattern": "(^.*\\{[^}]*$)", 28 | "decreaseIndentPattern": "^\\s*\\}" 29 | } 30 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.objective-c.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | ["{", "}"], 13 | ["[", "]"], 14 | ["(", ")"], 15 | ["\"", "\""], 16 | ["'", "'"], 17 | ["/**", " */"] 18 | ], 19 | "surroundingPairs": [ 20 | ["{", "}"], 21 | ["[", "]"], 22 | ["(", ")"], 23 | ["\"", "\""], 24 | ["'", "'"] 25 | ] 26 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.php.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", // "#" 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | { "open": "{", "close": "}", "notIn": ["string"] }, 13 | { "open": "[", "close": "]", "notIn": ["string"] }, 14 | { "open": "(", "close": ")", "notIn": ["string"] }, 15 | { "open": "'", "close": "'", "notIn": ["string", "comment"] }, 16 | { "open": "\"", "close": "\"", "notIn": ["string"] }, 17 | { "open": "/**", "close": " */", "notIn": ["string"] } 18 | ], 19 | "indentationRules": { 20 | "increaseIndentPattern": "({(?!.+}).*|\\(|\\[|((else(\\s)?)?if|else|for(each)?|while|switch).*:)\\s*(/[/*].*)?$", 21 | "decreaseIndentPattern": "^(.*\\*\\/)?\\s*((\\})|(\\)+[;,])|(\\][;,])|\\b(else:)|\\b((end(if|for(each)?|while|switch));))" 22 | } 23 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.rust.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | ["{", "}"], 13 | ["[", "]"], 14 | ["(", ")"], 15 | ["\"", "\""], 16 | ["/**", " */"] 17 | ], 18 | "surroundingPairs": [ 19 | ["{", "}"], 20 | ["[", "]"], 21 | ["(", ")"], 22 | ["\"", "\""], 23 | ["'", "'"] 24 | ] 25 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.scss.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "blockComment": ["/*", "*/"], 4 | "lineComment": "//" 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | { "open": "{", "close": "}", "notIn": ["string", "comment"] }, 13 | { "open": "[", "close": "]", "notIn": ["string", "comment"] }, 14 | { "open": "(", "close": ")", "notIn": ["string", "comment"] }, 15 | { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, 16 | { "open": "'", "close": "'", "notIn": ["string", "comment"] }, 17 | { "open": "/**", "close": " */", "notIn": ["string"] } 18 | ], 19 | "surroundingPairs": [ 20 | ["{", "}"], 21 | ["[", "]"], 22 | ["(", ")"], 23 | ["\"", "\""], 24 | ["'", "'"] 25 | ] 26 | } -------------------------------------------------------------------------------- /language-configuration/language-configuration.swift.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | ["{", "}"], 13 | ["[", "]"], 14 | ["(", ")"], 15 | ["\"", "\""], 16 | ["'", "'"], 17 | ["`", "`"], 18 | ["/**", " */"] 19 | ], 20 | "surroundingPairs": [ 21 | ["{", "}"], 22 | ["[", "]"], 23 | ["(", ")"], 24 | ["\"", "\""], 25 | ["'", "'"], 26 | ["`", "`"] 27 | ] 28 | } -------------------------------------------------------------------------------- /language-configuration/multi-line-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "languages": [ 3 | "c", 4 | "cpp", 5 | "csharp", 6 | "css", 7 | "go", 8 | "groovy", 9 | "java", 10 | "less", 11 | "objective-c", 12 | "objective-cpp", 13 | "php", 14 | "rust", 15 | "scss", 16 | "swift" 17 | ] 18 | } -------------------------------------------------------------------------------- /language-configuration/single-line-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "//": [ 3 | "c", 4 | "cpp", 5 | "csharp", 6 | "fsharp", 7 | "go", 8 | "groovy", 9 | "java", 10 | "javascript", 11 | "less", 12 | "objective-c", 13 | "objective-cpp", 14 | "php", 15 | "rust", 16 | "scss", 17 | "swift", 18 | "typescript" 19 | ], 20 | "#": [ 21 | "coffeescript", 22 | "dockerfile", 23 | "makefile", 24 | "perl", 25 | "powershell", 26 | "python", 27 | "r", 28 | "ruby", 29 | "yaml" 30 | ], 31 | ";": [ 32 | "clojure" 33 | ] 34 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "auto-comment-blocks", 3 | "displayName": "Auto Comment Blocks", 4 | "description": "Provides block comment completion for Javadoc-style multi-line comments and single-line comment blocks for most officially supported languages.", 5 | "version": "1.0.1", 6 | "publisher": "kevinkyang", 7 | "homepage": "https://github.com/kevinkyang/auto-comment-blocks", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/kevinkyang/auto-comment-blocks.git" 11 | }, 12 | "license": "SEE LICENSE IN LICENSE", 13 | "icon": "img/icon.png", 14 | "galleryBanner": { 15 | "color": "#171A29", 16 | "theme": "dark" 17 | }, 18 | "engines": { 19 | "vscode": "^1.12.0" 20 | }, 21 | "keywords": [ 22 | "auto", 23 | "comment", 24 | "block", 25 | "asterisk" 26 | ], 27 | "categories": [ 28 | "Other" 29 | ], 30 | "activationEvents": [ 31 | "*", 32 | "onCommand:auto-comment-blocks.singleLineBlock" 33 | ], 34 | "main": "./out/src/extension", 35 | "contributes": { 36 | "configuration": { 37 | "title": "Auto Comment Blocks", 38 | "properties": { 39 | "auto-comment-blocks.singleLineBlockOnEnter": { 40 | "type": "boolean", 41 | "default": false, 42 | "description": "If enabled, a new commented line is inserted when Enter is pressed, and comment blocks are broken by pressing Shift+Enter. If disabled (the default), a commented line is inserted when Shift+Enter is pressed, and comment blocks are broken by pressing Enter." 43 | }, 44 | "auto-comment-blocks.disabledLanguages": { 45 | "type": "array", 46 | "default": [], 47 | "description": "Add languageIds here to disable any comment completion for that language." 48 | }, 49 | "auto-comment-blocks.slashStyleBlocks": { 50 | "type": "array", 51 | "default": [], 52 | "description": "Add languageIds here to enable '//' and '///'-style single line comment blocks for that language. This allows unsupported languages to have comment completion." 53 | }, 54 | "auto-comment-blocks.hashStyleBlocks": { 55 | "type": "array", 56 | "default": [], 57 | "description": "Add languageIds here to enable '#'-style single line comment blocks for that language. This allows unsupported languages to have comment completion." 58 | }, 59 | "auto-comment-blocks.semicolonStyleBlocks": { 60 | "type": "array", 61 | "default": [], 62 | "description": "Add languageIds here to enable ';'-style single line comment blocks for that language. This allows unsupported languages to have comment completion." 63 | } 64 | } 65 | }, 66 | "languages": [ 67 | { 68 | "id": "c", 69 | "configuration": "./language-configuration/language-configuration.c.json" 70 | }, 71 | { 72 | "id": "cpp", 73 | "configuration": "./language-configuration/language-configuration.cpp.json" 74 | }, 75 | { 76 | "id": "css", 77 | "configuration": "./language-configuration/language-configuration.css.json" 78 | }, 79 | { 80 | "id": "scss", 81 | "configuration": "./language-configuration/language-configuration.scss.json" 82 | }, 83 | { 84 | "id": "groovy", 85 | "configuration": "./language-configuration/language-configuration.groovy.json" 86 | }, 87 | { 88 | "id": "php", 89 | "configuration": "./language-configuration/language-configuration.php.json" 90 | }, 91 | { 92 | "id": "objective-c", 93 | "configuration": "./language-configuration/language-configuration.objective-c.json" 94 | }, 95 | { 96 | "id": "objective-cpp", 97 | "configuration": "./language-configuration/language-configuration.objective-c.json" 98 | }, 99 | { 100 | "id": "less", 101 | "configuration": "./language-configuration/language-configuration.less.json" 102 | }, 103 | { 104 | "id": "swift", 105 | "configuration": "./language-configuration/language-configuration.swift.json" 106 | }, 107 | { 108 | "id": "rust", 109 | "configuration": "./language-configuration/language-configuration.rust.json" 110 | }, 111 | { 112 | "id": "go", 113 | "configuration": "./language-configuration/language-configuration.go.json" 114 | } 115 | ], 116 | "keybindings": [ 117 | { 118 | "command": "auto-comment-blocks.singleLineBlock", 119 | "key": "shift+enter", 120 | "when": "editorTextFocus" 121 | } 122 | ] 123 | }, 124 | "scripts": { 125 | "vscode:prepublish": "tsc -p ./", 126 | "compile": "tsc -watch -p ./", 127 | "postinstall": "node ./node_modules/vscode/bin/install", 128 | "test": "node ./node_modules/vscode/bin/test" 129 | }, 130 | "devDependencies": { 131 | "typescript": "^2.0.3", 132 | "vscode": "^1.0.0", 133 | "mocha": "^2.3.3", 134 | "@types/node": "^6.0.40", 135 | "@types/mocha": "^2.2.32" 136 | } 137 | } -------------------------------------------------------------------------------- /src/configuration.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Disposable, ExtensionContext, IndentAction, LanguageConfiguration, OnEnterRule, TextEditor, TextEditorEdit, commands, languages, workspace, } from 'vscode'; 4 | 5 | import { Rules } from './rules'; 6 | 7 | let fs = require('fs'); 8 | 9 | export class Configuration { 10 | 11 | private readonly extensionName: string = "auto-comment-blocks"; 12 | private readonly singleLineBlockCommand: string = 13 | "auto-comment-blocks.singleLineBlock"; 14 | private readonly singleLineConfigFile: string = __dirname + 15 | "/../../language-configuration/single-line-configuration.json"; 16 | private readonly multiLineConfigFile: string = __dirname + 17 | "/../../language-configuration/multi-line-configuration.json"; 18 | 19 | private readonly singleLineBlockOnEnter: string = "singleLineBlockOnEnter"; 20 | private readonly slashStyleBlocks: string = "slashStyleBlocks"; 21 | private readonly hashStyleBlocks: string = "hashStyleBlocks"; 22 | private readonly semicolonStyleBlocks: string = "semicolonStyleBlocks"; 23 | private readonly disabledLanguages: string = "disabledLanguages"; 24 | 25 | private disabledLanguageList: string[] = 26 | this.getConfiguration().get(this.disabledLanguages); 27 | private singleLineBlocksMap: Map = new Map(); 28 | 29 | private getConfiguration() { 30 | 31 | return workspace.getConfiguration(this.extensionName); 32 | } 33 | 34 | private isLangIdDisabled(langId: string) { 35 | 36 | return this.disabledLanguageList.indexOf(langId) !== -1; 37 | } 38 | 39 | private getMultiLineLanguages(): Array { 40 | 41 | let multiLineConfig = JSON.parse(fs.readFileSync( 42 | this.multiLineConfigFile, 'utf-8')); 43 | return multiLineConfig["languages"]; 44 | } 45 | 46 | private setLanguageConfiguration(langId: string, 47 | multiLine?: boolean, 48 | singleLineStyle?: string): Disposable { 49 | 50 | var langConfig: LanguageConfiguration = { 51 | onEnterRules: [] 52 | }; 53 | 54 | if (multiLine) { 55 | langConfig.onEnterRules = 56 | langConfig.onEnterRules.concat(Rules.multilineEnterRules); 57 | } 58 | 59 | let isOnEnter = this.getConfiguration().get( 60 | this.singleLineBlockOnEnter); 61 | if (isOnEnter && singleLineStyle) { 62 | if (singleLineStyle === '//') { 63 | langConfig.onEnterRules = 64 | langConfig.onEnterRules.concat(Rules.slashEnterRules); 65 | } else if (singleLineStyle === '#') { 66 | langConfig.onEnterRules = 67 | langConfig.onEnterRules.concat(Rules.hashEnterRules); 68 | } else if (singleLineStyle === ';') { 69 | langConfig.onEnterRules = 70 | langConfig.onEnterRules.concat(Rules.semicolonEnterRules); 71 | } 72 | } 73 | 74 | return languages.setLanguageConfiguration(langId, langConfig); 75 | } 76 | 77 | private getSingleLineLanguages() { 78 | 79 | let singleLineConfig: Object = JSON.parse(fs.readFileSync( 80 | this.singleLineConfigFile, 'utf-8')); 81 | let commentStyles = Object.keys(singleLineConfig); 82 | for (let key of commentStyles) { 83 | for (let langId of singleLineConfig[key]) { 84 | if (!this.isLangIdDisabled(langId)) { 85 | this.singleLineBlocksMap.set(langId, key); 86 | } 87 | } 88 | } 89 | 90 | // get user-customized langIds for this key and add to the map 91 | let customSlashLangs = 92 | this.getConfiguration().get(this.slashStyleBlocks); 93 | for (let langId of customSlashLangs) { 94 | if (langId && langId.length > 0) { 95 | this.singleLineBlocksMap.set(langId, '//'); 96 | } 97 | } 98 | 99 | let customHashLangs = 100 | this.getConfiguration().get(this.hashStyleBlocks); 101 | for (let langId of customHashLangs) { 102 | if (langId && langId.length > 0) { 103 | this.singleLineBlocksMap.set(langId, '#'); 104 | } 105 | } 106 | 107 | let customSemicolonLangs = 108 | this.getConfiguration().get(this.semicolonStyleBlocks); 109 | for (let langId of customSemicolonLangs) { 110 | if (langId && langId.length > 0) { 111 | this.singleLineBlocksMap.set(langId, ';'); 112 | } 113 | } 114 | } 115 | 116 | configureCommentBlocks(context: ExtensionContext) { 117 | 118 | this.getSingleLineLanguages(); 119 | 120 | // set language configurations 121 | let multiLineLangs = this.getMultiLineLanguages(); 122 | for (let [langId, style] of this.singleLineBlocksMap) { 123 | let multiLine = multiLineLangs.indexOf(langId) !== -1; 124 | let disposable = this.setLanguageConfiguration(langId, multiLine, style); 125 | context.subscriptions.push(disposable); 126 | } 127 | 128 | for (let langId of multiLineLangs) { 129 | if (!this.singleLineBlocksMap.has(langId) && 130 | !this.isLangIdDisabled(langId)) { 131 | 132 | let disposable = this.setLanguageConfiguration(langId, true); 133 | context.subscriptions.push(disposable); 134 | } 135 | } 136 | } 137 | 138 | private handleSingleLineBlock(textEditor: TextEditor, edit: TextEditorEdit) { 139 | 140 | let langId = textEditor.document.languageId; 141 | var style = this.singleLineBlocksMap.get(langId); 142 | if (style && textEditor.selection.isEmpty) { 143 | let line = textEditor.document.lineAt(textEditor.selection.active); 144 | let isCommentLine = true; 145 | var indentRegex: RegExp; 146 | if (style === '//' && line.text.search(/^\s*\/\/\s*/) !== -1) { 147 | indentRegex = /\//; 148 | if (line.text.search(/^\s*\/\/\/\s*/) !== -1) { 149 | style = '///'; 150 | } 151 | 152 | } else if (style === '#' && line.text.search(/^\s*#\s*/) !== -1) { 153 | indentRegex = /#/; 154 | 155 | } else if (style === ';' && line.text.search(/^\s*;\s*/) !== -1) { 156 | indentRegex = /;/; 157 | 158 | } else { 159 | isCommentLine = false; 160 | } 161 | 162 | if (!isCommentLine) { 163 | return; 164 | } 165 | 166 | var indentedNewLine = '\n' + 167 | line.text.substring(0, line.text.search(indentRegex)); 168 | let isOnEnter = this.getConfiguration().get( 169 | this.singleLineBlockOnEnter); 170 | if (!isOnEnter) { 171 | indentedNewLine += style + ' '; 172 | } 173 | 174 | edit.insert(textEditor.selection.active, indentedNewLine); 175 | } 176 | } 177 | 178 | registerCommands() { 179 | 180 | commands.registerTextEditorCommand(this.singleLineBlockCommand, 181 | (textEditor, edit, args) => { 182 | this.handleSingleLineBlock(textEditor, edit); 183 | }) 184 | } 185 | } -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { languages, commands, workspace, ExtensionContext, IndentAction, LanguageConfiguration, OnEnterRule, Disposable } from 'vscode'; 4 | import { Configuration } from './configuration'; 5 | 6 | let fs = require('fs'); 7 | let configuration = new Configuration(); 8 | 9 | export function activate(context: ExtensionContext) { 10 | 11 | configuration.configureCommentBlocks(context); 12 | configuration.registerCommands(); 13 | } 14 | 15 | export function deactivate() { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/rules.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { IndentAction, OnEnterRule } from 'vscode'; 4 | 5 | export class Rules { 6 | 7 | static readonly multilineEnterRules: OnEnterRule[] = [ 8 | { 9 | // e.g. /** | */ 10 | beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/, 11 | afterText: /^\s*\*\/$/, 12 | action: { indentAction: IndentAction.IndentOutdent, appendText: ' * ' } 13 | }, { 14 | // e.g. /** ...| 15 | beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/, 16 | action: { indentAction: IndentAction.None, appendText: ' * ' } 17 | }, { 18 | // e.g. /*! | */ 19 | beforeText: /^\s*\/\*\!(?!\/)([^\*]|\*(?!\/))*$/, 20 | afterText: /^\s*\*\/$/, 21 | action: { indentAction: IndentAction.IndentOutdent, appendText: ' * ' } 22 | }, { 23 | // e.g. /*! ...| 24 | beforeText: /^\s*\/\*\!(?!\/)([^\*]|\*(?!\/))*$/, 25 | action: { indentAction: IndentAction.None, appendText: ' * ' } 26 | }, { 27 | // e.g. * ...| 28 | beforeText: /^(\t|(\ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/, 29 | action: { indentAction: IndentAction.None, appendText: '* ' } 30 | }, { 31 | // e.g. */| 32 | beforeText: /^(\t|(\ ))*\ \*\/\s*$/, 33 | action: { indentAction: IndentAction.None, removeText: 1 } 34 | }, 35 | { 36 | // e.g. *-----*/| 37 | beforeText: /^(\t|(\ ))*\ \*[^/]*\*\/\s*$/, 38 | action: { indentAction: IndentAction.None, removeText: 1 } 39 | } 40 | ] 41 | 42 | static readonly slashEnterRules: OnEnterRule[] = [ 43 | { 44 | // e.g. // ...| 45 | beforeText: /^\s*\/\/(?!\/)/, 46 | action: { indentAction: IndentAction.None, appendText: '// '} 47 | }, 48 | { 49 | // e.g. /// ...| 50 | beforeText: /^\s*\/\/\//, 51 | action: { indentAction: IndentAction.None, appendText: '/// '} 52 | } 53 | ] 54 | 55 | static readonly hashEnterRules: OnEnterRule[] = [ 56 | { 57 | // e.g. # ...| 58 | beforeText: /^\s*#/, 59 | action: { indentAction: IndentAction.None, appendText: '# '} 60 | } 61 | ] 62 | 63 | static readonly semicolonEnterRules: OnEnterRule[] = [ 64 | { 65 | // e.g. ; ...| 66 | beforeText: /^\s*;/, 67 | action: { indentAction: IndentAction.None, appendText: '; '} 68 | } 69 | ] 70 | } -------------------------------------------------------------------------------- /test/extension.test.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Note: This example test is leveraging the Mocha test framework. 3 | // Please refer to their documentation on https://mochajs.org/ for help. 4 | // 5 | 6 | // The module 'assert' provides assertion methods from node 7 | import * as assert from 'assert'; 8 | 9 | // You can import and use all API from the 'vscode' module 10 | // as well as import your extension to test it 11 | import * as vscode from 'vscode'; 12 | import * as myExtension from '../src/extension'; 13 | 14 | // Defines a Mocha test suite to group tests of similar kind together 15 | suite("Extension Tests", () => { 16 | 17 | // Defines a Mocha unit test 18 | test("Something 1", () => { 19 | assert.equal(-1, [1, 2, 3].indexOf(5)); 20 | assert.equal(-1, [1, 2, 3].indexOf(0)); 21 | }); 22 | }); -------------------------------------------------------------------------------- /test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | var testRunner = require('vscode/lib/testrunner'); 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "." 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | ".vscode-test" 15 | ] 16 | } --------------------------------------------------------------------------------