From 47717e7ddcf110cb7cd2a7902ccc98ab146f97a5 Mon Sep 17 00:00:00 2001 From: Edgard Date: Tue, 12 Jan 2021 08:40:13 -0300 Subject: [PATCH] Added support to all languages --- package-lock.json | 25 ++++-- package.json | 95 ++------------------ src/extension.ts | 4 + src/parser.ts | 221 +++++++++++++++++----------------------------- 4 files changed, 110 insertions(+), 235 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1a751f2..3d274ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "better-comments", - "version": "2.0.5", + "version": "2.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -30,10 +30,16 @@ "js-tokens": "^4.0.0" } }, + "@types/json5": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.30.tgz", + "integrity": "sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==", + "dev": true + }, "@types/node": { - "version": "13.13.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.14.tgz", - "integrity": "sha512-Az3QsOt1U/K1pbCQ0TXGELTuTkPLOiFIQf3ILzbOyo0FqgV9SxRnxbxM5QlAveERZMHpZY+7u3Jz2tKyl+yg6g==", + "version": "13.13.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.39.tgz", + "integrity": "sha512-wct+WgRTTkBm2R3vbrFOqyZM5w0g+D8KnhstG9463CJBVC3UVZHMToge7iMBR1vDl/I+NWFHUeK9X+JcF0rWKw==", "dev": true }, "@types/vscode": { @@ -316,6 +322,14 @@ "esprima": "^4.0.0" } }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "requires": { + "minimist": "^1.2.5" + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -382,8 +396,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "mkdirp": { "version": "0.5.5", diff --git a/package.json b/package.json index 5b753ed..75eec82 100644 --- a/package.json +++ b/package.json @@ -25,90 +25,7 @@ "ui" ], "activationEvents": [ - "onLanguage:ada", - "onLanguage:al", - "onLanguage:apex", - "onLanguage:asciidoc", - "onLanguage:bibtex", - "onLanguage:brightscript", - "onLanguage:c", - "onLanguage:clojure", - "onLanguage:cfml", - "onLanguage:COBOL", - "onLanguage:coffeescript", - "onLanguage:cpp", - "onLanguage:csharp", - "onLanguage:css", - "onLanguage:d", - "onLanguage:dart", - "onLanguage:diagram", - "onLanguage:dockerfile", - "onLanguage:elixir", - "onLanguage:elm", - "onLanguage:erlang", - "onLanguage:flax", - "onLanguage:fsharp", - "onLanguage:fortran-modern", - "onLanguage:gdscript", - "onLanguage:genstat", - "onLanguage:go", - "onLanguage:graphql", - "onLanguage:groovy", - "onLanguage:haskell", - "onLanguage:html", - "onLanguage:haxe", - "onLanguage:hive-sql", - "onLanguage:kotlin", - "onLanguage:java", - "onLanguage:javascript", - "onLanguage:javascriptreact", - "onLanguage:jsonc", - "onLanguage:julia", - "onLanguage:latex", - "onLanguage:less", - "onLanguage:lisp", - "onLanguage:lua", - "onLanguage:makefile", - "onLanguage:markdown", - "onLanguage:matlab", - "onLanguage:nim", - "onLanguage:objective-c", - "onLanguage:objective-cpp", - "onLanguage:objectpascal", - "onLanguage:pascal", - "onLanguage:perl", - "onLanguage:perl6", - "onLanguage:pig", - "onLanguage:plaintext", - "onLanguage:plsql", - "onLanguage:php", - "onLanguage:powershell", - "onLanguage:puppet", - "onLanguage:python", - "onLanguage:r", - "onLanguage:racket", - "onLanguage:ruby", - "onLanguage:rust", - "onLanguage:scala", - "onLanguage:sas", - "onLanguage:sass", - "onLanguage:scss", - "onLanguage:shaderlab", - "onLanguage:shellscript", - "onLanguage:sql", - "onLanguage:stata", - "onLanguage:stylus", - "onLanguage:swift", - "onLanguage:tcl", - "onLanguage:terraform", - "onLanguage:twig", - "onLanguage:typescript", - "onLanguage:typescriptreact", - "onLanguage:vb", - "onLanguage:verilog", - "onLanguage:vue", - "onLanguage:xml", - "onLanguage:yaml" + "*" ], "galleryBanner": { "color": "#e3f4ff", @@ -190,10 +107,14 @@ } }, "devDependencies": { + "@types/json5": "0.0.30", + "@types/node": "^13.13.39", "@types/vscode": "^1.47.0", - "@types/node": "^13.11.1", + "tslint": "^6.1.2", "typescript": "^3.4.3", - "vsce": "^1.77.0", - "tslint": "^6.1.2" + "vsce": "^1.77.0" + }, + "dependencies": { + "json5": "^2.1.3" } } diff --git a/src/extension.ts b/src/extension.ts index 4fc4df1..af431c8 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,6 +7,10 @@ export function activate(context: vscode.ExtensionContext) { let activeEditor: vscode.TextEditor; let parser: Parser = new Parser(); + vscode.extensions.onDidChange(() => { + parser.updateLanguagesDefinitions(); + }, null, context.subscriptions); + // Called to handle events below let updateDecorations = function (useHash = false) { // * if no active window is open, return diff --git a/src/parser.ts b/src/parser.ts index 95e14bc..79cb9ae 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,4 +1,7 @@ import * as vscode from 'vscode'; +import * as path from 'path'; +import * as fs from 'fs'; +import * as json5 from 'json5' interface CommentTag { tag: string; @@ -22,6 +25,11 @@ interface Contributions { }]; } +interface CommentConfig { + lineComment?: string; + blockComment?: [string, string]; +} + export class Parser { private tags: CommentTag[] = []; private expression: string = ""; @@ -46,8 +54,62 @@ export class Parser { // Read from the package.json private contributions: Contributions = vscode.workspace.getConfiguration('better-comments') as any; + private readonly languageToConfigPath = new Map(); + + private readonly commentConfig = new Map(); + public constructor() { this.setTags(); + this.updateLanguagesDefinitions(); + } + + /** + * Generate a map of language configuration file by language defined by extensions + * External extensions can override default configurations os VSCode + */ + public updateLanguagesDefinitions() { + this.commentConfig.clear(); + + for (const extension of vscode.extensions.all) { + const packageJSON = extension.packageJSON as any; + if (packageJSON.contributes && packageJSON.contributes.languages) { + for (const language of packageJSON.contributes.languages) { + if (language.configuration) { + const configPath = path.join(extension.extensionPath, language.configuration); + this.languageToConfigPath.set(language.id, configPath); + } + } + } + } + } + + /** + * Return the comment config for `languageCode` + * @param languageCode The short code of the current language + */ + private getCommentConfig (languageCode: string): CommentConfig | undefined { + if (this.commentConfig.has(languageCode)) { + return this.commentConfig.get(languageCode); + } + + if (!this.languageToConfigPath.has(languageCode)) { + return undefined; + } + + const file = this.languageToConfigPath.get(languageCode) as string; + + const content = fs.readFileSync(file, {encoding: 'utf8'}); + + try { + // use json5, because the config can contains comments + const config = json5.parse(content); + + this.commentConfig.set(languageCode, config.comments); + return config.comments; + } catch (error) { + this.commentConfig.set(languageCode, undefined); + return undefined; + } } /** @@ -243,172 +305,47 @@ export class Parser { this.supportedLanguage = true; this.ignoreFirstLine = false; this.isPlainText = false; + this.delimiter = ""; + this.blockCommentStart = ""; + this.blockCommentEnd = ""; - switch (languageCode) { + const config = this.getCommentConfig(languageCode); - case "asciidoc": - this.setCommentFormat("//", "////", "////"); - break; + if (config) { + if (config.blockComment) { + this.setCommentFormat(config.lineComment || null, config.blockComment[0], config.blockComment[1]); + } else if (config.lineComment) { + this.delimiter = this.escapeRegExp(config.lineComment); + } + } else { + this.supportedLanguage = false; + } + switch (languageCode) { case "apex": case "javascript": case "javascriptreact": case "typescript": case "typescriptreact": - this.setCommentFormat("//", "/*", "*/"); this.highlightJSDoc = true; break; - case "al": - case "c": - case "cpp": - case "csharp": - case "dart": - case "flax": - case "fsharp": - case "go": - case "groovy": - case "haxe": - case "java": - case "jsonc": - case "kotlin": - case "less": - case "pascal": - case "objectpascal": - case "php": - case "rust": - case "scala": - case "sass": - case "scss": - case "shaderlab": - case "stylus": - case "swift": - case "verilog": - case "vue": - this.setCommentFormat("//", "/*", "*/"); - break; - - case "css": - this.setCommentFormat("/*", "/*", "*/"); - break; - - case "coffeescript": - case "dockerfile": - case "gdscript": - case "graphql": - case "julia": - case "makefile": - case "perl": - case "perl6": - case "puppet": - case "r": - case "ruby": - case "shellscript": - case "tcl": - case "yaml": - this.delimiter = "#"; - break; - - case "tcl": - this.delimiter = "#"; - this.ignoreFirstLine = true; - break; - case "elixir": case "python": - this.setCommentFormat("#", '"""', '"""'); + case "tcl": this.ignoreFirstLine = true; break; - - case "nim": - this.setCommentFormat("#", "#[", "]#"); - break; - - case "powershell": - this.setCommentFormat("#", "<#", "#>"); - break; - - case "ada": - case "hive-sql": - case "pig": - case "plsql": - case "sql": - this.delimiter = "--"; - break; - - case "lua": - this.setCommentFormat("--", "--[[", "]]"); - break; - - case "elm": - case "haskell": - this.setCommentFormat("--", "{-", "-}"); - break; - - case "brightscript": - case "diagram": // ? PlantUML is recognized as Diagram (diagram) - case "vb": - this.delimiter = "'"; - break; - - case "bibtex": - case "erlang": - case "latex": - case "matlab": - this.delimiter = "%"; - break; - case "clojure": - case "racket": - case "lisp": - this.delimiter = ";"; - break; - - case "terraform": - this.setCommentFormat("#", "/*", "*/"); - break; - - case "COBOL": - this.delimiter = this.escapeRegExp("*>"); - break; - - case "fortran-modern": - this.delimiter = "c"; - break; - - case "SAS": - case "stata": - this.setCommentFormat("*", "/*", "*/"); - break; - - case "html": - case "markdown": - case "xml": - this.setCommentFormat(""); - break; - - case "twig": - this.setCommentFormat("{#", "{#", "#}"); - break; - - case "genstat": - this.setCommentFormat("\\", '"', '"'); + case "css": + this.delimiter = this.escapeRegExp("/*"); break; - case "cfml": - this.setCommentFormat(""); - break; - case "plaintext": this.isPlainText = true; // If highlight plaintext is enabeld, this is a supported language this.supportedLanguage = this.contributions.highlightPlainText; break; - - default: - this.supportedLanguage = false; - break; } }