diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f0b5bd..f7cdebc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ## [Unreleased] +* workspace counter in status bar. + +## [1.3.3] + +### Added + +- New Command : `Check available languages`. + +## [1.3.2] + +### Fixed + +- Replaced the file API used with one provided by vscode. ## [1.3.1] diff --git a/README.md b/README.md index 8140d35..61e35fa 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ VS Code extension: counts blank lines, comment lines, and physical lines of sour ### Count in workspace -* Open the command palette and select `VSCode Counter: Count lines in workspace`. +* Open the command palette and select `VSCodeCounter: Count lines in workspace`. ![](images/count_workspace.gif) @@ -30,11 +30,16 @@ VS Code extension: counts blank lines, comment lines, and physical lines of sour ### Real-time counter -* Open the command palette and select `VSCode Counter: Toggle Real-time Counter Visibility`. +* Open the command palette and select `VSCodeCounter: Toggle Real-time Counter Visibility`. ![](images/realtime_counter.png) +### Check available languages +* Open the command palette and select `VSCodeCounter: Check available languages`. + ![](images/avail_langs.png) + + * Available languages can be increased by adding language extensions. ## Extension Settings diff --git a/images/avail_langs.png b/images/avail_langs.png new file mode 100644 index 0000000..ecc3665 Binary files /dev/null and b/images/avail_langs.png differ diff --git a/package.json b/package.json index dbee71c..96a3489 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-counter", "displayName": "VS Code Counter", "description": "Count lines of code in many programming languages.", - "version": "1.3.2", + "version": "1.3.3", "publisher": "uctakeoff", "author": { "name": "Ushiyama Kentaro" @@ -36,7 +36,8 @@ "*", "onCommand:extension.vscode-counter.countInFile", "onCommand:extension.vscode-counter.countInDirectory", - "onCommand:extension.vscode-counter.countInWorkspace" + "onCommand:extension.vscode-counter.countInWorkspace", + "onCommand:extension.vscode-counter.outputAvailableLanguages" ], "contributes": { "commands": [ @@ -57,6 +58,12 @@ "category": "VSCodeCounter", "title": "%commands.countInWorkspace.title%", "icon": "images/icon.png" + }, + { + "command": "extension.vscode-counter.outputAvailableLanguages", + "category": "VSCodeCounter", + "title": "%commands.outputAvailableLanguages.title%", + "icon": "images/icon.png" } ], "menus": { diff --git a/package.nls.ja.json b/package.nls.ja.json index 0c6b9ce..39bb5ad 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -2,6 +2,7 @@ "commands.countInFile.title": "リアルタイムコードカウンタの表示・非表示切り替え", "commands.countInDirectory.title": "ディレクトリ内のコード行を数える", "commands.countInWorkspace.title": "ワークスペース内のコード行を数える", + "commands.outputAvailableLanguages.title": "利用可能な言語を確認する", "configuration.showInStatusBar.description": "現在のファイルのカウント結果をリアルタイムでステータスバーに表示する.", "configuration.useGitignore.description": "対象ファイルを除外するために '.gitignore' を使う.", "configuration.useFilesExclude.description": "対象ファイルを除外するために 'files.exclude' 設定を使う.", diff --git a/package.nls.json b/package.nls.json index 6a947e0..9a15675 100644 --- a/package.nls.json +++ b/package.nls.json @@ -2,6 +2,7 @@ "commands.countInFile.title": "Toggle Real-time Counter Visibility", "commands.countInDirectory.title": "Count lines in directory", "commands.countInWorkspace.title": "Count lines in workspace", + "commands.outputAvailableLanguages.title": "Check available languages", "configuration.showInStatusBar.description": "Whether to show the count result of the current file on the status bar in real time.", "configuration.useGitignore.description": "Whether to use '.gitignore' files for excluding files.", "configuration.useFilesExclude.description": "Whether to use setting 'files.exclude' for excluding files.", diff --git a/src/LineCounter.ts b/src/LineCounter.ts index 833b397..b4e6c50 100644 --- a/src/LineCounter.ts +++ b/src/LineCounter.ts @@ -16,9 +16,7 @@ export default class LineCounter this.id = id; } public addAlias(aliases: string[]) { - if (aliases) { - this.aliases.push(...aliases); - } + this.aliases.push(...aliases); } public addLineCommentRule(...tokens: string[]) { this.lineComment.push(...tokens); diff --git a/src/extension.ts b/src/extension.ts index c6bb8ca..3f391ba 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,7 +3,7 @@ // Import the module and reference it with the alias vscode in your code below import * as vscode from 'vscode'; import * as path from 'path'; -import * as fs from 'graceful-fs'; +// import * as fs from 'graceful-fs'; import LineCounter from './LineCounter'; import Gitignore from './Gitignore'; import * as JSONC from 'jsonc-parser'; @@ -44,7 +44,8 @@ export function activate(context: vscode.ExtensionContext) { codeCountController, vscode.commands.registerCommand('extension.vscode-counter.countInWorkspace', () => codeCountController.countInWorkspace()), vscode.commands.registerCommand('extension.vscode-counter.countInDirectory', (targetDir: vscode.Uri|undefined) => codeCountController.countInDirectory(targetDir)), - vscode.commands.registerCommand('extension.vscode-counter.countInFile', () => codeCountController.toggleVisible()) + vscode.commands.registerCommand('extension.vscode-counter.countInFile', () => codeCountController.toggleVisible()), + vscode.commands.registerCommand('extension.vscode-counter.outputAvailableLanguages', () => codeCountController.outputAvailableLanguages()) ); } // this method is called when your extension is deactivated @@ -95,6 +96,9 @@ class CodeCounterController { public toggleVisible() { this.configuration.update('showInStatusBar', !this.isVisible); } + public outputAvailableLanguages() { + this.codeCounter.outputAvailableLanguages(); + } public countInDirectory(targetDir: vscode.Uri|undefined) { try { const folders = workspaceFolders(); @@ -248,16 +252,19 @@ class CodeCounter { private outputChannel: vscode.OutputChannel|null = null; private statusBarItem: vscode.StatusBarItem|null = null; private configuration: vscode.WorkspaceConfiguration; + private langExtensions: VscodeLangExtension[]; private lineCounterTable: LineCounterTable; constructor(configuration: vscode.WorkspaceConfiguration) { - log(`create CodeCounter`); + log(`build CodeCounter start`); this.configuration = configuration; const confFiles = vscode.workspace.getConfiguration("files", null); - this.lineCounterTable = new LineCounterTable(this.configuration, [...Object.entries(confFiles.get('associations', {}))]); + this.langExtensions = loadLanguageExtensions(); + this.lineCounterTable = new LineCounterTable(this.langExtensions, this.configuration, [...Object.entries(confFiles.get('associations', {}))]); if (this.getConf('showInStatusBar', false)) { this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); } + log(`create CodeCounter end`); } dispose() { if (this.statusBarItem !== null) { @@ -278,6 +285,12 @@ class CodeCounter { this.outputChannel.show(); this.outputChannel.appendLine(text); } + public outputAvailableLanguages() { + this.langExtensions.forEach((lang) => { + this.toOutputChannel(`${lang.id} : aliases[${lang.aliases}], extensions[${lang.extensions}], filenames:[${lang.filenames}]`); + }); + this.toOutputChannel(`VS Code Counter : available all ${this.langExtensions.length} languages.`); + } public countLinesInDirectory(targetUri: vscode.Uri, outputDirUri: vscode.Uri) { // const outputDir = path.resolve(outputDirUri.fsPath, this.getConf('outputDirectory', '.VSCodeCounter')); const outputDir = buildUri(outputDirUri, this.getConf('outputDirectory', '.VSCodeCounter')); @@ -407,6 +420,37 @@ class CodeCounter { } } +class VscodeLangExtension { + extensionPath: string; + id:string; + aliases:string[]; + filenames:string[]; + extensions:string[]; + configuration:vscode.Uri|undefined; + + constructor(extensionPath:string, language:{id:string, aliases:string[]|undefined, filenames:string[]|undefined, extensions:string[]|undefined, configuration:string|undefined}) { + this.extensionPath = extensionPath; + this.id = language.id; + this.aliases = language.aliases !== undefined ? language.aliases : []; + this.filenames = language.filenames !== undefined ? language.filenames : []; + this.extensions = language.extensions !== undefined ? language.extensions : []; + this.configuration = language.configuration !== undefined ? vscode.Uri.file(path.join(this.extensionPath, language.configuration)) : undefined; + } +} +function loadLanguageExtensions() : VscodeLangExtension[] { + const ret : VscodeLangExtension[] = []; + vscode.extensions.all.forEach(ex => { + const contributes = ex.packageJSON.contributes; + if (contributes !== undefined) { + const languages = contributes.languages; + if (languages !== undefined) { + (languages as Array).forEach(l => ret.push(new VscodeLangExtension(ex.extensionPath, l))); + } + } + }); + return ret; +} + class LineCounterTable { private langIdTable: Map; private aliasTable: Map; @@ -414,7 +458,7 @@ class LineCounterTable { private filenameRules: Map; private associations: [string, string][]; - constructor(conf: vscode.WorkspaceConfiguration, associations: [string, string][]) { + constructor(langExtensions: VscodeLangExtension[], conf: vscode.WorkspaceConfiguration, associations: [string, string][]) { this.langIdTable = new Map(); this.aliasTable = new Map(); this.fileextRules = new Map(); @@ -423,38 +467,28 @@ class LineCounterTable { log(`associations : ${this.associations.length}\n[${this.associations.join("],[")}]`); const confJsonTable = new Map(); + const decoderU8 = new TextDecoder('utf8'); - vscode.extensions.all.forEach(ex => { - const contributes = ex.packageJSON.contributes; - if (contributes !== undefined) { - const languages = contributes.languages; - if (languages !== undefined) { - languages.forEach((lang: {id:string, aliases:string[]|undefined, filenames:string[]|undefined, extensions:string[]|undefined, configuration:string|undefined}) => { - const lineCounter = getOrSetFirst(this.langIdTable, lang.id, () => new LineCounter(lang.id)); - if (lang.aliases !== undefined) { - lineCounter.addAlias(lang.aliases); - lang.aliases.forEach((alias:string) => { - this.aliasTable.set(alias, lineCounter); - }); - } - // log(`${lang.id} : aliases[${lang.aliases}], extensions[${lang.extensions}], filenames:[${lang.filenames}]`); - const confpath = lang.configuration ? path.join(ex.extensionPath, lang.configuration) : ""; - if (confpath.length > 0) { - // log(` language conf file: ${confpath}`); - const v = getOrSetFirst(confJsonTable, confpath, () => JSONC.parse(fs.readFileSync(confpath, "utf8"))); - // log(` ${JSON.stringify(v)}`); - lineCounter.addCommentRule(v.comments); - } - if (lang.extensions !== undefined) { - (lang.extensions as Array).forEach(ex => this.fileextRules.set(ex.startsWith('.') ? ex : `.${ex}`, lineCounter)); - } - if (lang.filenames !== undefined) { - (lang.filenames as Array).forEach(ex => this.filenameRules.set(ex, lineCounter)); - } - }); - } + langExtensions.forEach(lang => { + // log(`${lang.id} : aliases[${lang.aliases}], extensions[${lang.extensions}], filenames:[${lang.filenames}], configuration:[${lang.configuration}]`); + const lineCounter = getOrSetFirst(this.langIdTable, lang.id, () => new LineCounter(lang.id)); + lineCounter.addAlias(lang.aliases); + lang.aliases.forEach((alias:string) => { + this.aliasTable.set(alias, lineCounter); + }); + const confpath = lang.configuration; + if (confpath !== undefined) { + vscode.workspace.fs.readFile(confpath).then(data => { + // log(`"${confpath}" : ${data.length}B`); + const v = getOrSetFirst(confJsonTable, confpath.toString(), () => JSONC.parse(decoderU8.decode(data))); + // log(` ${JSON.stringify(v)}`); + lineCounter.addCommentRule(v.comments); + }); } + lang.extensions.forEach(ex => this.fileextRules.set(ex.startsWith('.') ? ex : `.${ex}`, lineCounter)); + lang.filenames.forEach(ex => this.filenameRules.set(ex, lineCounter)); }); + class BlockPattern { public types: string[] = []; public patterns: string[][] = [];