From 8a13c890b7862a6cf9e414c23cb972e9b00c75b6 Mon Sep 17 00:00:00 2001 From: uctakeoff Date: Wed, 1 Jul 2020 16:48:57 +0900 Subject: [PATCH 1/3] Refactoring --- src/LineCounter.ts | 59 ++--- src/extension.ts | 572 ++++++++++++++++++++------------------------- 2 files changed, 266 insertions(+), 365 deletions(-) diff --git a/src/LineCounter.ts b/src/LineCounter.ts index b4e6c50..e061730 100644 --- a/src/LineCounter.ts +++ b/src/LineCounter.ts @@ -2,42 +2,17 @@ export default class LineCounter { - private id: string; - private aliases: string[] = []; - private lineComment: string[] = []; - public blockComment: {begin:string, end:string}[] = []; - public blockString: {begin:string, end:string}[] = []; + public readonly name: string; + private lineComments: string[]; + private blockComments: [string, string][]; + private blockStrings: [string, string][]; - get languageId(): string { - return this.aliases.length > 0 ? this.aliases[0] : this.id; + constructor(name:string, lineComments:string[], blockComments:[string,string][], blockStrings:[string,string][]) { + this.name = name; + this.lineComments = lineComments; + this.blockComments = blockComments; + this.blockStrings = blockStrings; } - - constructor(id:string) { - this.id = id; - } - public addAlias(aliases: string[]) { - this.aliases.push(...aliases); - } - public addLineCommentRule(...tokens: string[]) { - this.lineComment.push(...tokens); - } - public addBlockCommentRule(...tokenPairs: {begin:string, end:string}[]) { - this.blockComment.push(...tokenPairs); - } - public addBlockStringRule(...tokenPairs: {begin:string, end:string}[]) { - this.blockString.push(...tokenPairs); - } - public addCommentRule(rule: any) { - if (rule) { - if (typeof(rule.lineComment) === 'string' && rule.lineComment.length > 0) { - this.lineComment.push(rule.lineComment as string); - } - if (rule.blockComment && (rule.blockComment.length >= 2)) { - this.addBlockCommentRule({begin: rule.blockComment[0], end: rule.blockComment[1]}); - } - } - } - public count(text: string): {code:number, comment:number, blank:number} { enum LineType {Code, Comment, Blank} @@ -72,28 +47,28 @@ export default class LineCounter } } else { // now is line comment. - if (this.lineComment.some(lc => line.startsWith(lc))) { + if (this.lineComments.some(lc => line.startsWith(lc))) { type = LineType.Comment; break; } { let index = -1; - const range = this.blockComment.find(bc => { index = line.indexOf(bc.begin, i); return index >= 0; }); + const range = this.blockComments.find(bc => { index = line.indexOf(bc[0], i); return index >= 0; }); if (range !== undefined) { // start block comment type = index === 0 ? LineType.Comment : LineType.Code; - blockCommentEnd = range.end; - i = index + range.begin.length; + blockCommentEnd = range[1]; + i = index + range[0].length; continue; } } type = LineType.Code; { let index = -1; - const rabge = this.blockString.find(bc => { index = line.indexOf(bc.begin, i); return index >= 0; }); - if (rabge !== undefined) { - blockStringEnd = rabge.end; - i = index + rabge.begin.length; + const range = this.blockStrings.find(bc => { index = line.indexOf(bc[0], i); return index >= 0; }); + if (range !== undefined) { + blockStringEnd = range[1]; + i = index + range[0].length; continue; } } diff --git a/src/extension.ts b/src/extension.ts index 7c2f1d9..1cbf622 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -9,6 +9,7 @@ import Gitignore from './Gitignore'; import * as JSONC from 'jsonc-parser'; import * as minimatch from 'minimatch'; import { TextDecoder, TextEncoder } from 'util'; +// import { debug } from 'console'; const EXTENSION_ID = 'uctakeoff.vscode-counter'; const EXTENSION_NAME = 'VSCodeCounter'; @@ -33,12 +34,7 @@ export function activate(context: vscode.ExtensionContext) { if (ext !== undefined && (typeof ext.packageJSON.version === 'string')) { version = ext.packageJSON.version; } - // Use the console to output diagnostic information (console.log) and errors (console.error) - // This line of code will only be executed once when your extension is activated log(`${EXTENSION_ID} ver.${version} now active! : ${context.extensionPath}`); - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json const codeCountController = new CodeCounterController(); context.subscriptions.push( codeCountController, @@ -59,8 +55,11 @@ const workspaceFolders = (): readonly vscode.WorkspaceFolder[] => { class CodeCounterController { private configuration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(CONFIGURATION_SECTION); - private codeCounter_: CodeCounter|null = null; + private codeCounter_: LineCounterTable|null = null; + private statusBarItem: vscode.StatusBarItem|null = null; + private outputChannel: vscode.OutputChannel|null = null; private disposable: vscode.Disposable; + constructor() { // subscribe to selection change and editor activation events let subscriptions: vscode.Disposable[] = []; @@ -70,34 +69,43 @@ class CodeCounterController { vscode.workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, subscriptions); // create a combined disposable from both event subscriptions this.disposable = vscode.Disposable.from(...subscriptions); - if (this.isVisible) { - this.codeCounter.countCurrentFile(); - } } dispose() { + this.statusBarItem?.dispose(); + this.statusBarItem = null; + this.outputChannel?.dispose(); + this.outputChannel = null; this.disposable.dispose(); - this.disposeCodeCounter(); + this.codeCounter_ = null; } - private get codeCounter() { - if (this.codeCounter_ === null) { - this.codeCounter_ = new CodeCounter(this.configuration); + private async getCodeCounter() { + if (this.codeCounter_) { + return this.codeCounter_ } + // const langs = new Map();//Object.entries(configuration.get<{[key:string]:VscodeLanguageConf}>('languages', {}))); + const langs = await loadLanguageExtensions(new Map()); + log(`loadLang = ${langs.size}`); + const confFiles = vscode.workspace.getConfiguration("files", null); + this.codeCounter_ = new LineCounterTable(langs, Object.entries(confFiles.get<{[key:string]:string}>('associations', {}))); + this.configuration.update('languages', objectFromEntries(langs), vscode.ConfigurationTarget.Global); return this.codeCounter_; } - private disposeCodeCounter() { - if (this.codeCounter_ !== null) { - this.codeCounter_.dispose(); - this.codeCounter_ = null; - } - } - private get isVisible() { - return this.configuration.get('showInStatusBar', false); - } public toggleVisible() { - this.configuration.update('showInStatusBar', !this.isVisible); + if (!this.statusBarItem) { + this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); + this.countFile(vscode.window.activeTextEditor?.document); + } else { + this.statusBarItem.dispose(); + this.statusBarItem = null; + } } public outputAvailableLanguages() { - this.codeCounter.outputAvailableLanguages(); + this.getCodeCounter().then(c => { + c.entries().forEach((lang, id) => { + this.toOutputChannel(`${id} : aliases[${lang.aliases}], extensions[${lang.extensions}], filenames:[${lang.filenames}]`); + }); + this.toOutputChannel(`VS Code Counter : available all ${c.entries().size} languages.`); + }); } public countInDirectory(targetDir: vscode.Uri|undefined) { try { @@ -105,7 +113,7 @@ class CodeCounterController { if (folders.length <= 0) { vscode.window.showErrorMessage(`[${EXTENSION_NAME}] No open workspace`); } else if (targetDir !== undefined) { - this.codeCounter.countLinesInDirectory(targetDir, folders[0].uri); + this.countLinesInDirectory(targetDir, folders[0].uri); } else { const option = { value : folders[0].uri.toString(true), @@ -113,8 +121,8 @@ class CodeCounterController { prompt: "Input Directory Path. " }; vscode.window.showInputBox(option).then(uri => { - if (uri !== undefined) { - this.codeCounter.countLinesInDirectory(vscode.Uri.parse(uri), folders[0].uri); + if (uri) { + this.countLinesInDirectory(vscode.Uri.parse(uri), folders[0].uri); } }); } @@ -128,11 +136,11 @@ class CodeCounterController { if (folders.length <= 0) { vscode.window.showErrorMessage(`[${EXTENSION_NAME}] No open workspace`); } else if (folders.length === 1) { - this.codeCounter.countLinesInDirectory(folders[0].uri, folders[0].uri); + this.countLinesInDirectory(folders[0].uri, folders[0].uri); } else { vscode.window.showWorkspaceFolderPick().then((folder) => { if (folder) { - this.codeCounter.countLinesInDirectory(folder.uri, folder.uri); + this.countLinesInDirectory(folder.uri, folder.uri); } }); } @@ -147,15 +155,15 @@ class CodeCounterController { workspaceFolders().forEach((f) => log(` [${f.index}] ${f.name} : ${f.uri}`)); } private onDidChangeActiveTextEditor(e: vscode.TextEditor|undefined) { - if (this.codeCounter_ !== null) { + if (this.codeCounter_) { log(`onDidChangeActiveTextEditor(${!e ? 'undefined' : e.document.uri})`); - this.codeCounter.countFile((e !== undefined) ? e.document : undefined); + this.countFile(e?.document); } } private onDidChangeTextDocument(e: vscode.TextDocumentChangeEvent) { - if (this.codeCounter_ !== null) { + if (this.codeCounter_) { log(`onDidChangeTextDocument(${e.document.uri})`); - this.codeCounter.countFile(e.document); + this.countFile(e.document); } } private onDidChangeConfiguration() { @@ -163,12 +171,44 @@ class CodeCounterController { if (JSON.stringify(this.configuration) !== JSON.stringify(newConf)) { log(`onDidChangeConfiguration()`); this.configuration = newConf; - this.disposeCodeCounter(); - if (this.isVisible) { - this.codeCounter.countCurrentFile(); - } + this.codeCounter_ = null; + this.countFile(vscode.window.activeTextEditor?.document); } } + private countLinesInDirectory(targetUri: vscode.Uri, outputDirUri: vscode.Uri) { + this.getCodeCounter().then(c => { + countLinesInDirectory(c, targetUri, outputDirUri, this.configuration, this.toOutputChannel); + }); + } + private showStatusBar(text: string) { + if (this.statusBarItem) { + this.statusBarItem.show(); + this.statusBarItem.text = text; + } + } + private countFile(doc: vscode.TextDocument|undefined) { + if (!doc) { + this.showStatusBar(`${EXTENSION_NAME}:Unsupported`); + } else { + this.getCodeCounter().then(c =>{ + const lineCounter = c.getById(doc.languageId) || c.getByUri(doc.uri); + if (lineCounter) { + const result = lineCounter?.count(doc.getText()); + this.showStatusBar(`Code:${result.code} Comment:${result.comment} Blank:${result.blank}`); + } else { + this.showStatusBar(`${EXTENSION_NAME}:Unsupported`); + } + }); + } + } + private toOutputChannel(text: string) { + if (!this.outputChannel) { + this.outputChannel = vscode.window.createOutputChannel(EXTENSION_NAME); + } + this.outputChannel.show(); + this.outputChannel.appendLine(text); + } + } const encodingTable = new Map([ ['big5hkscs', 'big5-hkscs'], @@ -248,272 +288,200 @@ function readFileAll(fileUris: vscode.Uri[]) : Promise<{uri:vscode.Uri, data:Uin } }); } -class CodeCounter { - private outputChannel: vscode.OutputChannel|null = null; - private statusBarItem: vscode.StatusBarItem|null = null; - private configuration: vscode.WorkspaceConfiguration; - private langExtensions: VscodeLangExtension[]; - private lineCounterTable: LineCounterTable; +function countLinesInDirectory(lineCounterTable: LineCounterTable, targetUri: vscode.Uri, outputDirUri: vscode.Uri, configuration: vscode.WorkspaceConfiguration, consoleOut:(text:string)=>void) { + const outputDir = buildUri(outputDirUri, configuration.get('outputDirectory', '.VSCodeCounter')); + log(`countLinesInDirectory : ${targetUri}, output dir: ${outputDir}`); + const confFiles = vscode.workspace.getConfiguration("files", null); + const includes = configuration.get('include', ['**/*']); + const excludes = configuration.get('exclude', []); + if (configuration.get('useFilesExclude', true)) { + excludes.push(...Object.keys(confFiles.get('exclude', {}))); + } + const encoding = confFiles.get('encoding', 'utf8'); + const decoder = new TextDecoder(encodingTable.get(encoding) || encoding); + const decoderU8 = new TextDecoder('utf8'); - constructor(configuration: vscode.WorkspaceConfiguration) { - log(`build CodeCounter start`); - this.configuration = configuration; - const confFiles = vscode.workspace.getConfiguration("files", null); - 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) { - this.statusBarItem.dispose(); - } - if (this.outputChannel !== null) { - this.outputChannel.dispose(); - } - log(`dispose CodeCounter`); - } - private getConf(section: string, defaultValue: T): T { - return this.configuration.get(section, defaultValue); - } - private toOutputChannel(text: string) { - if (this.outputChannel === null) { - this.outputChannel = vscode.window.createOutputChannel(EXTENSION_NAME); - } - 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')); - log(`countLinesInDirectory : ${targetUri}, output dir: ${outputDir}`); - const confFiles = vscode.workspace.getConfiguration("files", null); - const includes = this.getConf>('include', ['**/*']); - const excludes = this.getConf>('exclude', []); - if (this.getConf('useFilesExclude', true)) { - excludes.push(...Object.keys(confFiles.get('exclude', {}))); - } - const encoding = confFiles.get('encoding', 'utf8'); - const decoder = new TextDecoder(encodingTable.get(encoding) || encoding); - const decoderU8 = new TextDecoder('utf8'); - - excludes.push(vscode.workspace.asRelativePath(outputDir)); - log(`includes : "${includes.join('", "')}"`); - log(`excludes : "${excludes.join('", "')}"`); + excludes.push(vscode.workspace.asRelativePath(outputDir)); + log(`includes : "${includes.join('", "')}"`); + log(`excludes : "${excludes.join('", "')}"`); - new Promise((resolve: (p: vscode.Uri[])=> void, reject: (reason: any) => void) => { - vscode.workspace.findFiles(`{${includes.join(',')}}`, `{${excludes.join(',')}}`).then((files: vscode.Uri[]) => { - const fileUris = files.filter(uri => uri.path.startsWith(targetUri.path)); - if (this.getConf('useGitignore', true)) { - log(`target : ${fileUris.length} files -> use .gitignore`); - vscode.workspace.findFiles('**/.gitignore', '').then((gitignoreFiles: vscode.Uri[]) => { - gitignoreFiles.forEach(f => log(`use gitignore : ${f}`)); - readFileAll(gitignoreFiles.sort()).then((values) => { - const gitignores = new Gitignore('').merge(...values.map(p => new Gitignore(decoderU8.decode(p.data), dirUri(p.uri).fsPath))); - resolve(fileUris.filter(p => gitignores.excludes(p.fsPath))); - }, - reject - ); - // const t = .map(p => vscode.workspace.fs.readFile(p)); - // const gitignores = new Gitignore('').merge(...gitignoreFiles.map(uri => uri.fsPath).sort().map(p => new Gitignore(fs.readFileSync(p, 'utf8'), path.dirname(p)))); - // resolve(fileUris.filter(p => gitignores.excludes(p.fsPath))); + new Promise((resolve: (p: vscode.Uri[])=> void, reject: (reason: any) => void) => { + vscode.workspace.findFiles(`{${includes.join(',')}}`, `{${excludes.join(',')}}`).then((files: vscode.Uri[]) => { + const fileUris = files.filter(uri => uri.path.startsWith(targetUri.path)); + if (configuration.get('useGitignore', true)) { + log(`target : ${fileUris.length} files -> use .gitignore`); + vscode.workspace.findFiles('**/.gitignore', '').then((gitignoreFiles: vscode.Uri[]) => { + gitignoreFiles.forEach(f => log(`use gitignore : ${f}`)); + readFileAll(gitignoreFiles.sort()).then((values) => { + const gitignores = new Gitignore('').merge(...values.map(p => new Gitignore(decoderU8.decode(p.data), dirUri(p.uri).fsPath))); + resolve(fileUris.filter(p => gitignores.excludes(p.fsPath))); }, reject ); - } else { - resolve(fileUris); - } - }); - }).then((fileUris: vscode.Uri[]) => { - log(`target : ${fileUris.length} files`); - return new Promise((resolve: (value: Result[])=> void, reject: (reason: string) => void) => { - const results: Result[] = []; - if (fileUris.length <= 0) { - resolve(results); - } - const ignoreUnsupportedFile = this.getConf('ignoreUnsupportedFile', true); - let fileCount = 0; - fileUris.forEach(fileUri => { - const lineCounter = this.lineCounterTable.getByUri(fileUri); - if (lineCounter !== undefined) { -/* - fs.readFile(fileUri.fsPath, encoding, (err, data) => { - ++fileCount; - if (err) { - this.toOutputChannel(`"${fileUri}" Read Error : ${err.message}.`); - results.push(new Result(fileUri, '(Read Error)')); - } else { - results.push(new Result(fileUri, lineCounter.languageId, lineCounter.count(data))); - } - if (fileCount === fileUris.length) { - resolve(results); - } - }); -*/ - vscode.workspace.fs.readFile(fileUri).then(data => { - ++fileCount; - try { - results.push(new Result(fileUri, lineCounter.languageId, lineCounter.count(decoder.decode(data)))); - } catch (e) { - this.toOutputChannel(`"${fileUri}" Read Error : ${e.message}.`); - results.push(new Result(fileUri, '(Read Error)')); - } - if (fileCount === fileUris.length) { - resolve(results); - } - }, - (reason: any) => { - this.toOutputChannel(`"${fileUri}" Read Error : ${reason}.`); + // const t = .map(p => vscode.workspace.fs.readFile(p)); + // const gitignores = new Gitignore('').merge(...gitignoreFiles.map(uri => uri.fsPath).sort().map(p => new Gitignore(fs.readFileSync(p, 'utf8'), path.dirname(p)))); + // resolve(fileUris.filter(p => gitignores.excludes(p.fsPath))); + }, + reject + ); + } else { + resolve(fileUris); + } + }); + }).then((fileUris: vscode.Uri[]) => { + log(`target : ${fileUris.length} files`); + return new Promise((resolve: (value: Result[])=> void, reject: (reason: string) => void) => { + const results: Result[] = []; + if (fileUris.length <= 0) { + resolve(results); + } + const ignoreUnsupportedFile = configuration.get('ignoreUnsupportedFile', true); + let fileCount = 0; + fileUris.forEach(fileUri => { + const lineCounter = lineCounterTable.getByUri(fileUri); + if (lineCounter) { + vscode.workspace.fs.readFile(fileUri).then(data => { + ++fileCount; + try { + results.push(new Result(fileUri, lineCounter.name, lineCounter.count(decoder.decode(data)))); + } catch (e) { + consoleOut(`"${fileUri}" Read Error : ${e.message}.`); results.push(new Result(fileUri, '(Read Error)')); - }); - } else { - if (!ignoreUnsupportedFile) { - results.push(new Result(fileUri, '(Unsupported)')); } - ++fileCount; if (fileCount === fileUris.length) { resolve(results); } + }, + (reason: any) => { + consoleOut(`"${fileUri}" Read Error : ${reason}.`); + results.push(new Result(fileUri, '(Read Error)')); + }); + } else { + if (!ignoreUnsupportedFile) { + results.push(new Result(fileUri, '(Unsupported)')); } - }); + ++fileCount; + if (fileCount === fileUris.length) { + resolve(results); + } + } }); - }).then((results: Result[]) => { - outputResults(targetUri, results, outputDir, this.configuration); - }).catch((reason: string) => { - vscode.window.showErrorMessage(`[${EXTENSION_NAME}] countLinesInDirectory() failed.`, reason); }); - } - private countFile_(doc: vscode.TextDocument|undefined) { - if (doc !== undefined) { - const lineCounter = this.lineCounterTable.getById(doc.languageId) || this.lineCounterTable.getByUri(doc.uri); - log(`${doc.uri}: ${JSON.stringify(lineCounter)}`); - if (lineCounter !== undefined) { - const result = lineCounter.count(doc.getText()); - // return `Code:${result.code} Comment:${result.comment} Blank:${result.blank} Total:${result.code+result.comment+result.blank}`; - return `Code:${result.code} Comment:${result.comment} Blank:${result.blank}`; - } - } - return `${EXTENSION_NAME}:Unsupported`; - } - public countFile(doc: vscode.TextDocument|undefined) { - if (this.statusBarItem !== null) { - this.statusBarItem.show(); - this.statusBarItem.text = this.countFile_(doc); - } - } - public countCurrentFile() { - // Get the current text editor - const editor = vscode.window.activeTextEditor; - if (editor !== undefined) { - this.countFile(editor.document); - } else { - this.countFile(undefined); - } - } + }).then((results: Result[]) => { + outputResults(targetUri, results, outputDir, configuration); + }).catch((reason: string) => { + vscode.window.showErrorMessage(`[${EXTENSION_NAME}] countLinesInDirectory() failed.`, reason); + }); } -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; - } +type VscodeLang = { + id:string + aliases?:string[] + filenames?:string[] + extensions?:string[] + configuration?:string +}; +type VscodeLanguageConf = { + aliases:string[] + filenames:string[] + extensions:string[] + lineComments: string[] + blockComments: [string,string][] + blockStrings: [string,string][] } -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))); - } +const append = (langExtTable: Map, l:VscodeLang) => { + const langExt = getOrSet(langExtTable, l.id, ():VscodeLanguageConf => { + return { + aliases:[], + filenames:[], + extensions:[], + lineComments:[], + blockComments:[], + blockStrings:[] + } + }); + langExt.aliases.push(...(l.aliases??[])); + langExt.filenames.push(...(l.filenames??[])); + langExt.extensions.push(...(l.extensions??[])); + return langExt; +} + +function loadLanguageExtensions(langExtTable: Map) : Promise> { + return new Promise((resolve: (values: Map)=> void, reject: (reason: any) => void) => { + if (vscode.extensions.all.length <= 0) { + resolve(langExtTable); + } else { + let finishedCount = 0; + let totalCount = 0; + const decoderU8 = new TextDecoder('utf8'); + vscode.extensions.all.forEach(ex => { + const languages = ex.packageJSON.contributes?.languages as Array ?? undefined; + if (languages) { + totalCount += languages.length + languages.forEach(l => { + const langExt = append(langExtTable, l); + if (l.configuration) { + const confUrl = vscode.Uri.file(path.join(ex.extensionPath, l.configuration)); + vscode.workspace.fs.readFile(confUrl).then(data => { + // log(`${confUrl} ${data.length}B :${l.id}`); + const langConf = JSONC.parse(decoderU8.decode(data)) as vscode.LanguageConfiguration; + if (langConf.comments) { + if (langConf.comments.lineComment) { + langExt.lineComments.push(langConf.comments.lineComment); + } + if (langConf.comments.blockComment && langConf.comments.blockComment.length >= 2) { + langExt.blockComments.push(langConf.comments.blockComment); + } + } + if (++finishedCount >= totalCount) { + resolve(langExtTable); + } + }, + (reason:any) => { + log(`${confUrl} : error ${reason}`); + if (++finishedCount >= totalCount) { + resolve(langExtTable); + } + }); + + } else { + if (++finishedCount >= totalCount) { + resolve(langExtTable); + } + } + }); + } + }); } }); - return ret; } class LineCounterTable { + private langExtensions: Map; private langIdTable: Map; private aliasTable: Map; private fileextRules: Map; private filenameRules: Map; private associations: [string, string][]; - constructor(langExtensions: VscodeLangExtension[], conf: vscode.WorkspaceConfiguration, associations: [string, string][]) { + constructor(langExtensions: Map, associations: [string, string][]) { + this.langExtensions = langExtensions; this.langIdTable = new Map(); this.aliasTable = new Map(); this.fileextRules = new Map(); this.filenameRules = new Map(); this.associations = associations; log(`associations : ${this.associations.length}\n[${this.associations.join("],[")}]`); - - const confJsonTable = new Map(); - const decoderU8 = new TextDecoder('utf8'); - - 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[][] = []; - } - conf.get< Array >('blockComment', []).forEach(patterns => { - patterns.types.forEach(id => { - const lineCounter = this.getById(id) || this.getByPath(id); - if (lineCounter) { - // log(`addBlockStringRule("${id}", ${tokenPairs.map(t => t.begin + t.end).join('|')}) => [${lineCounter.name}]`); - lineCounter.addBlockStringRule(...patterns.patterns.map(pat => { return {begin: pat[0], end: pat[1]}; })); - } - }); + langExtensions.forEach((lang, id) => { + const langName = lang.aliases.length > 0 ? lang.aliases[0] : id; + const lineCounter = new LineCounter(langName, lang.lineComments, lang.blockComments, lang.blockStrings); + lang.aliases.forEach(v => this.aliasTable.set(v, lineCounter)); + lang.extensions.forEach(v => this.fileextRules.set(v.startsWith('.') ? v : `.${v}`, lineCounter)); + lang.filenames.forEach(v => this.filenameRules.set(v, lineCounter)); }); - - // log(`confJsonTable : ${confJsonTable.size} =======================================================================`); - // confJsonTable.forEach((v, n) => { log(`${n}:\n ${JSON.stringify(v)}`); }); - // log(`this.filenameRules : ${this.filenameRules.size} =======================================================================`); - // this.filenameRules.forEach((v, n) => { log(`${n}\t ${JSON.stringify(v)}`); }); - // log(`this.fileextRules : ${this.fileextRules.size} =======================================================================`); - // this.fileextRules.forEach((v, n) => { log(`${n}\t ${JSON.stringify(v)}`); }); - // log(`this.langIdTable : ${this.langIdTable.size} =======================================================================`); - // this.langIdTable.forEach((v, n) => { log(`${n}\t ${JSON.stringify(v)}`); }); - // log(`this.aliasTable : ${this.aliasTable.size} =======================================================================`); - // this.aliasTable.forEach((v, n) => { log(`${n}\t ${JSON.stringify(v)}`); }); } + public entries = () => this.langExtensions; + public getById(langId: string) { return this.langIdTable.get(langId) || this.aliasTable.get(langId); } @@ -527,18 +495,10 @@ class LineCounterTable { return (patType !== undefined) ? this.getById(patType[1]) : undefined; } public getByUri(uri: vscode.Uri) { - return this.getByPath(uri.path); + return this.getByPath(uri.fsPath); } - - // public countById(filepath: string, text: string): {languageId:string, code:number, comment:number, blank:number}|undefined { - // const counter = this.getById(filepath); - // return (counter !== undefined) ? {languageId: counter.languageId, ...counter.count(text)} : undefined; - // } - // public countByPath(filepath: string, text: string): {languageId:string, code:number, comment:number, blank:number}|undefined { - // const counter = this.getByPath(filepath); - // return (counter !== undefined) ? {languageId: counter.languageId, ...counter.count(text)} : undefined; - // } } + async function outputResults(workspaceUri: vscode.Uri, results: Result[], outputDirUri: vscode.Uri, conf: vscode.WorkspaceConfiguration) { const resultTable = new ResultTable(workspaceUri, results, conf.get('printNumberWithCommas', true) ? toStringWithCommas : (obj:any) => obj.toString() ); const endOfLine = conf.get('endOfLine', '\n'); @@ -571,7 +531,7 @@ async function outputResults(workspaceUri: vscode.Uri, results: Result[], output if (conf.get('outputAsMarkdown', true)) { const detailsUri = buildUri(outputDirUri, 'details.md'); const resultsUri = buildUri(outputDirUri, 'results.md'); - const promise = conf.get('outputMarkdownSeparately.', true) + const promise = conf.get('outputMarkdownSeparately', true) ? writeTextFile(detailsUri, [ '# Details', '', @@ -695,14 +655,14 @@ class ResultTable { .forEach((result) => { let parent = path.dirname(path.relative(this.targetDirPath, result.filename)); while (parent.length >= 0) { - getOrSetFirst(this.dirResultTable, parent, () => new Statistics(parent)).append(result); + getOrSet(this.dirResultTable, parent, () => new Statistics(parent)).append(result); const p = path.dirname(parent); if (p === parent) { break; } parent = p; } - getOrSetFirst(this.langResultTable, result.language, () => new Statistics(result.language)).append(result); + getOrSet(this.langResultTable, result.language, () => new Statistics(result.language)).append(result); this.total.append(result); }); } @@ -850,7 +810,14 @@ class ResultTable { } -function getOrSetFirst(map: Map, key: K, otherwise: () => V) { +function objectFromEntries(map: Map) { + const obj: any = {} + map.forEach((v,id)=>{ + obj[id] = v + }) + return obj; +} +function getOrSet(map: Map, key: K, otherwise: () => V) { let v = map.get(key); if (v === undefined) { v = otherwise(); @@ -858,47 +825,6 @@ function getOrSetFirst(map: Map, key: K, otherwise: () => V) { } return v; } -/* -function makeDirectories(dirpath: string) { - if (fs.existsSync(dirpath)) { - return true; - } - const parent = path.dirname(dirpath); - if ((parent !== dirpath) && makeDirectories(parent)) { - fs.mkdirSync(dirpath); - return true; - } else { - return false; - } -} -function showTextFile(outputFilename: string) { - log(`showTextFile : ${outputFilename}`); - return new Promise((resolve: (editor: vscode.TextEditor)=> void, reject: (err: any) => void) => { - vscode.workspace.openTextDocument(outputFilename) - .then((doc) => { - return vscode.window.showTextDocument(doc, vscode.ViewColumn.One, true); - }, err => { - reject(err); - }).then((editor) => { - resolve(editor); - }, err => { - reject(err); - }); - }); -} -function writeTextFile(outputFilename: string, text: string) { - log(`writeTextFile : ${outputFilename} ${text.length}B`); - return new Promise((resolve: (filename: string)=> void, reject: (err: NodeJS.ErrnoException) => void) => { - fs.writeFile(outputFilename, text, err => { - if (err) { - reject(err); - } else { - resolve(outputFilename); - } - }); - }); -} -*/ function makeDirectories_(dirpath: vscode.Uri, resolve: ()=> void, reject: (reason: string) => void) { // log(`makeDirectories ${dirpath}`); vscode.workspace.fs.stat(dirpath).then((value) => { From a15f940ca89e4c2925776ce1442c6a4d2135ca83 Mon Sep 17 00:00:00 2001 From: uctakeoff Date: Sat, 4 Jul 2020 20:39:04 +0900 Subject: [PATCH 2/3] Add Command: saveLanguageConfigurations. Update: dependent libraries --- package-lock.json | 646 +++++++++++++++++++++++++++++--------------- package.json | 169 ++++++------ package.nls.ja.json | 14 +- package.nls.json | 14 +- src/extension.ts | 286 ++++++++++++-------- 5 files changed, 712 insertions(+), 417 deletions(-) diff --git a/package-lock.json b/package-lock.json index df921dd..4dd9281 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,42 +1,41 @@ { "name": "vscode-counter", - "version": "1.3.4", + "version": "1.3.5", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.10.4" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", "dev": true, "requires": { - "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } @@ -57,21 +56,21 @@ "dev": true }, "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", "dev": true }, "@types/node": { - "version": "12.12.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.6.tgz", - "integrity": "sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA==", + "version": "14.0.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", + "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==", "dev": true }, "@types/vscode": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.40.0.tgz", - "integrity": "sha512-5kEIxL3qVRkwhlMerxO7XuMffa+0LBl+iG2TcRa0NsdoeSFLkt/9hJ02jsi/Kvc6y8OVF2N2P2IHP5S4lWf/5w==", + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.46.0.tgz", + "integrity": "sha512-8m9wPEB2mcRqTWNKs9A9Eqs8DrQZt0qNFO8GkxBOnyW6xR//3s77SoMgb/nY1ctzACsZXwZj3YRTDsn4bAoaUw==", "dev": true }, "agent-base": { @@ -84,9 +83,9 @@ } }, "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-regex": { @@ -104,6 +103,16 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -113,11 +122,29 @@ "sprintf-js": "~1.0.2" } }, + "array.prototype.map": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", + "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.4" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -127,6 +154,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -167,6 +203,22 @@ } } }, + "chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" + } + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -257,9 +309,9 @@ } }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "emoji-regex": { @@ -269,27 +321,49 @@ "dev": true }, "es-abstract": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", - "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", + "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "es-get-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", + "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", + "dev": true, + "requires": { + "es-abstract": "^1.17.4", + "has-symbols": "^1.0.1", + "is-arguments": "^1.0.4", + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-string": "^1.0.5", + "isarray": "^2.0.5" } }, "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { "is-callable": "^1.1.4", @@ -324,19 +398,23 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "flat": { @@ -354,6 +432,13 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -380,6 +465,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -402,9 +496,9 @@ "dev": true }, "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, "he": { @@ -466,6 +560,21 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", @@ -473,15 +582,21 @@ "dev": true }, "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-fullwidth-code-point": { @@ -490,30 +605,85 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", + "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.1" + "has-symbols": "^1.0.1" } }, + "is-set": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", + "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "requires": { - "has-symbols": "^1.0.0" + "has-symbols": "^1.0.1" } }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "iterate-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", + "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", + "dev": true + }, + "iterate-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", + "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", + "dev": true, + "requires": { + "es-get-iterator": "^1.0.2", + "iterate-iterator": "^1.0.1" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -531,18 +701,17 @@ } }, "jsonc-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.0.tgz", - "integrity": "sha512-4fLQxW1j/5fWj6p78vAlAafoCKtuBm6ghv+Ij5W2DrDx0qE+ZdEl2c6Ko1mgJNF5ftX1iEWQQ4Ap7+3GlhjkOA==" + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", + "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -552,12 +721,12 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^2.4.2" } }, "minimatch": { @@ -569,87 +738,69 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "mocha": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", - "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz", + "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==", "dev": true, "requires": { - "ansi-colors": "3.2.3", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", + "chokidar": "3.3.1", "debug": "3.2.6", - "diff": "3.5.0", + "diff": "4.0.2", "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", + "find-up": "4.1.0", + "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "3.13.1", - "log-symbols": "2.2.0", + "log-symbols": "3.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", + "ms": "2.1.2", "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", + "promise.allsettled": "1.0.2", + "serialize-javascript": "3.0.0", + "strip-json-comments": "3.0.1", + "supports-color": "7.1.0", + "which": "2.0.2", "wide-align": "1.1.3", - "yargs": "13.3.0", - "yargs-parser": "13.1.1", + "workerpool": "6.0.0", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", "yargs-unparser": "1.6.0" - }, - "dependencies": { - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true }, "object-keys": { @@ -670,16 +821,6 @@ "object-keys": "^1.0.11" } }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -690,21 +831,21 @@ } }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, "p-try": { @@ -714,9 +855,9 @@ "dev": true }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { @@ -731,6 +872,34 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "promise.allsettled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", + "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", + "dev": true, + "requires": { + "array.prototype.map": "^1.0.1", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "iterate-value": "^1.0.0" + } + }, + "readdirp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.7" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -744,9 +913,9 @@ "dev": true }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -767,6 +936,12 @@ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, + "serialize-javascript": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", + "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==", + "dev": true + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -789,24 +964,24 @@ "strip-ansi": "^4.0.0" } }, - "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5" } }, - "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5" } }, "strip-ansi": { @@ -819,30 +994,47 @@ } }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + } + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" } }, "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "dev": true }, "tslint": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.2.tgz", + "integrity": "sha512-UyNrLdK3E0fQG/xWNqAFAC5ugtFyPO4JJR1KyyfQAyzR8W0fTRrC91A8Wej4BntFzcvETdCSDa/4PnNYJQLYiA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -853,19 +1045,11 @@ "glob": "^7.1.1", "js-yaml": "^3.13.1", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "mkdirp": "^0.5.3", "resolve": "^1.3.2", "semver": "^5.3.0", - "tslib": "^1.8.0", + "tslib": "^1.10.0", "tsutils": "^2.29.0" - }, - "dependencies": { - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true - } } }, "tsutils": { @@ -878,15 +1062,15 @@ } }, "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz", + "integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==", "dev": true }, "vscode-test": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.2.2.tgz", - "integrity": "sha512-7bF8tINeynZ52Lg8vsJI2mFKnXD0HtVJoOfYzEUhMspo44lPRTcVFSg+PIY3jy8OTd3dMFaxAscBznCvGgdM2g==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", + "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", "dev": true, "requires": { "http-proxy-agent": "^2.1.0", @@ -895,9 +1079,9 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -918,6 +1102,12 @@ "string-width": "^1.0.2 || 2" } }, + "workerpool": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", + "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", + "dev": true + }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -970,9 +1160,9 @@ "dev": true }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -984,7 +1174,7 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" }, "dependencies": { "ansi-regex": { @@ -993,6 +1183,40 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -1016,9 +1240,9 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index fd59ed0..f9314f5 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,13 @@ "name": "vscode-counter", "displayName": "VS Code Counter", "description": "Count lines of code in many programming languages.", - "version": "1.3.5", + "version": "2.0.0", "publisher": "uctakeoff", "author": { "name": "Ushiyama Kentaro" }, "engines": { - "vscode": "^1.40.0" + "vscode": "^1.46.0" }, "galleryBanner": { "color": "#BF9C68", @@ -26,18 +26,18 @@ "Programming Languages" ], "keywords": [ - "code", "count", - "counter", + "loc", + "code", "step", "line" ], "activationEvents": [ - "*", "onCommand:extension.vscode-counter.countInFile", "onCommand:extension.vscode-counter.countInDirectory", "onCommand:extension.vscode-counter.countInWorkspace", - "onCommand:extension.vscode-counter.outputAvailableLanguages" + "onCommand:extension.vscode-counter.outputAvailableLanguages", + "onCommand:extension.vscode-counter.saveLanguageConfigurations" ], "contributes": { "commands": [ @@ -64,6 +64,12 @@ "category": "VSCodeCounter", "title": "%commands.outputAvailableLanguages.title%", "icon": "icon.png" + }, + { + "command": "extension.vscode-counter.saveLanguageConfigurations", + "category": "VSCodeCounter", + "title": "%commands.saveLanguageConfigurations.title%", + "icon": "icon.png" } ], "menus": { @@ -79,11 +85,6 @@ "type": "object", "title": "VSCode Counter", "properties": { - "VSCodeCounter.showInStatusBar": { - "description": "%configuration.showInStatusBar.description%", - "type": "boolean", - "default": false - }, "VSCodeCounter.useGitignore": { "description": "%configuration.useGitignore.description%", "type": "boolean", @@ -171,72 +172,80 @@ ], "default": "markdown" }, - "VSCodeCounter.blockComment": { - "description": "%configuration.blockComment.description%", - "type": "array", - "items": { - "type": "object", - "properties": { - "types": { - "description": "%configuration.blockComment.types.description%", - "type": "array", - "minItems": 1, - "items": { - "type": "string" - } - }, - "patterns": { - "description": "%configuration.blockComment.patterns.description%", - "type": "array", - "items": { + "VSCodeCounter.saveLocation": { + "description": "%configuration.saveLocation.description%", + "type": "string", + "enum": [ + "global settings", + "workspace settings", + "output directory" + ], + "default": "global settings" + }, + "VSCodeCounter.languages": { + "description": "%configuration.languages.description%", + "type": "object", + "default": {}, + "patternProperties": { + ".*": { + "type": "object", + "title": "language configuration", + "properties": { + "aliases": { + "type": "array", + "description": "%configuration.languages.aliases.description%", + "items": { + "type": "string" + } + }, + "filenames": { "type": "array", - "minItems": 2, - "maxItems": 2, + "description": "%configuration.languages.filenames.description%", "items": { "type": "string" } + }, + "extensions": { + "type": "array", + "description": "%configuration.languages.extensions.description%", + "items": { + "type": "string" + } + }, + "lineComments": { + "type": "array", + "description": "%configuration.languages.lineComments.description%", + "items": { + "type": "string" + } + }, + "blockComments": { + "type": "array", + "description": "%configuration.languages.blockComments.description%", + "items": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "string" + } + } + }, + "blockStrings": { + "type": "array", + "description": "%configuration.languages.blockStrings.description%", + "items": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "string" + } + } } } } - }, - "default": [ - { - "types": [ - "cpp" - ], - "patterns": [ - [ - "R\"(", - ")\"" - ] - ] - }, - { - "types": [ - "lua" - ], - "patterns": [ - [ - "[[", - "]]" - ] - ] - }, - { - "types": [ - ".js", - ".jsx", - ".ts", - ".tsx" - ], - "patterns": [ - [ - "`", - "`" - ] - ] - } - ] + } } } } @@ -250,20 +259,20 @@ "test": "node ./out/test/runTest.js" }, "devDependencies": { - "@types/glob": "^7.1.1", + "@types/glob": "^7.1.2", "@types/graceful-fs": "^4.1.3", "@types/minimatch": "^3.0.3", - "@types/mocha": "^5.2.7", - "@types/node": "^12.11.7", - "@types/vscode": "^1.40.0", - "glob": "^7.1.5", - "mocha": "^6.2.2", - "tslint": "^5.20.0", - "typescript": "^3.6.4", - "vscode-test": "^1.2.2" + "@types/mocha": "^7.0.2", + "@types/node": "^14.0.14", + "@types/vscode": "^1.46.0", + "glob": "^7.1.6", + "mocha": "^8.0.1", + "tslint": "^6.1.2", + "typescript": "^3.9.6", + "vscode-test": "^1.4.0" }, "dependencies": { - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^2.2.1", "minimatch": "^3.0.4" } } diff --git a/package.nls.ja.json b/package.nls.ja.json index 39bb5ad..a0f714a 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -3,7 +3,8 @@ "commands.countInDirectory.title": "ディレクトリ内のコード行を数える", "commands.countInWorkspace.title": "ワークスペース内のコード行を数える", "commands.outputAvailableLanguages.title": "利用可能な言語を確認する", - "configuration.showInStatusBar.description": "現在のファイルのカウント結果をリアルタイムでステータスバーに表示する.", + "commands.saveLanguageConfigurations.title": "収集した言語設定を保存する", + "configuration.useGitignore.description": "対象ファイルを除外するために '.gitignore' を使う.", "configuration.useFilesExclude.description": "対象ファイルを除外するために 'files.exclude' 設定を使う.", "configuration.printNumberWithCommas.description": "数値をカンマ区切りで出力する (CSVを除く).", @@ -17,7 +18,12 @@ "configuration.outputAsMarkdown.description": "結果をMarkdown形式で出力する.", "configuration.outputMarkdownSeparately.description": "Markdown結果を概要と詳細で分けて出力する.", "configuration.outputPreviewType.description": "カウント後にプレビューする出力ファイルの種類.", - "configuration.blockComment.description": "ブロックコメント(ヒアドキュメント)の先頭と末尾を示すパターンを定義する.\n複数行にまたがるような文字列を判別するために使用する.この内部に現れたコメント行はコード行とみなされる.\n -types: 言語の種類. languageId(例 cpp, csharp, javascript...), エイリアス名(例 C++, C#, JavaScript), 拡張子(eg .cpp, .cs, .js) のいずれかで指定する.\n - patterns: コメント範囲を示すパターン.", - "configuration.blockComment.types.description": "言語の種類.\n languageId(例 cpp, csharp, javascript...), エイリアス名(例 C++, C#, JavaScript), 拡張子(eg .cpp, .cs, .js) のいずれかで指定する.", - "configuration.blockComment.patterns.description": "コメント範囲を示すパターン." + "configuration.saveLocation.description": "集めた言語設定を保存する場所を指定する.", + "configuration.languages.description": "保存された言語設定.", + "configuration.languages.aliases.description": "言語の別名.", + "configuration.languages.filenames.description": "言語に関連付けられたファイル名.", + "configuration.languages.extensions.description": "言語に関連付けられたファイル拡張子.", + "configuration.languages.lineComments.description": "行コメントを開始する文字列.", + "configuration.languages.blockComments.description": "ブロックコメントの開始と終了を示す文字列.", + "configuration.languages.blockStrings.description": "複数行文字列(ヒアドキュメント)の先頭と末尾を示す文字列." } \ No newline at end of file diff --git a/package.nls.json b/package.nls.json index 9a15675..80b2679 100644 --- a/package.nls.json +++ b/package.nls.json @@ -3,7 +3,8 @@ "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.", + "commands.saveLanguageConfigurations.title": "Save the collected language configurations", + "configuration.useGitignore.description": "Whether to use '.gitignore' files for excluding files.", "configuration.useFilesExclude.description": "Whether to use setting 'files.exclude' for excluding files.", "configuration.printNumberWithCommas.description": "Whether to print a number with commas as thousands separators.(except for CSV)", @@ -17,7 +18,12 @@ "configuration.outputAsMarkdown.description": "Whether to output the result as a Markdown file.", "configuration.outputMarkdownSeparately.description": "Whether to output summary and details separately.", "configuration.outputPreviewType.description": "Type of output file to preview after counting.", - "configuration.blockComment.description": "Define patterns indicating the beginning and end of the block document(here document).\nIt is used to distinguish between strings that span multiple lines, and the comment lines displayed in it are considered code lines.\n - types: Language types. Allows you to specify languageId(eg cpp, csharp, javascript...), aliases(eg C++, C#, JavaScript), and extensions(eg .cpp, .cs, .js).\n - patterns: patterns indicating the range of comments.", - "configuration.blockComment.types.description": "Language types. \nAllows you to specify languageId(eg cpp, csharp, javascript...), aliases(eg C++, C#, JavaScript), and extensions(eg .cpp, .cs, .js).", - "configuration.blockComment.patterns.description": "patterns indicating the range of comments." + "configuration.saveLocation.description": "Specify where to store the collected language configurations.", + "configuration.languages.description": "Saved Language Configurations.", + "configuration.languages.aliases.description": "Name aliases for the language.", + "configuration.languages.filenames.description": "Filenames associated to the language.", + "configuration.languages.extensions.description": "File extensions associated to the language.", + "configuration.languages.lineComments.description": "The character sequence that starts a line comment.", + "configuration.languages.blockComments.description": "The character sequence indicating the beginning and end of the block comment.", + "configuration.languages.blockStrings.description": "The character sequence indicating the beginning and end of the block document(here document)." } \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 1cbf622..a70f7a9 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,7 +3,6 @@ // 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 LineCounter from './LineCounter'; import Gitignore from './Gitignore'; import * as JSONC from 'jsonc-parser'; @@ -24,16 +23,13 @@ const toStringWithCommas = (obj: any) => { return obj.toString(); } }; -const log = (message: string) => console.log(`[${EXTENSION_NAME}] ${new Date().toISOString()} ${message}`); +const log = (message: string, ...items:any[]) => console.log(`[${EXTENSION_NAME}] ${new Date().toISOString()} ${message}`, ...items); +const showError = (message: string, ...items:any[]) => vscode.window.showErrorMessage(`[${EXTENSION_NAME}] ${message}`, ...items); // this method is called when your extension is activated // your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { - let version = "-"; - const ext = vscode.extensions.getExtension(EXTENSION_ID); - if (ext !== undefined && (typeof ext.packageJSON.version === 'string')) { - version = ext.packageJSON.version; - } + const version = vscode.extensions.getExtension(EXTENSION_ID)?.packageJSON?.version; log(`${EXTENSION_ID} ver.${version} now active! : ${context.extensionPath}`); const codeCountController = new CodeCounterController(); context.subscriptions.push( @@ -41,6 +37,7 @@ export function activate(context: vscode.ExtensionContext) { 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.saveLanguageConfigurations', () => codeCountController.saveLanguageConfigurations()), vscode.commands.registerCommand('extension.vscode-counter.outputAvailableLanguages', () => codeCountController.outputAvailableLanguages()) ); } @@ -48,13 +45,18 @@ export function activate(context: vscode.ExtensionContext) { export function deactivate() { } -const workspaceFolders = (): readonly vscode.WorkspaceFolder[] => { - const folders = vscode.workspace.workspaceFolders; - return !folders ? [] : folders; -}; +async function currentWorkspaceFolder() { + const folders = vscode.workspace.workspaceFolders ?? []; + if (folders.length <= 0) { + return undefined; + } else if (folders.length === 1) { + return folders[0]; + } else { + return await vscode.window.showWorkspaceFolderPick(); + } +} class CodeCounterController { - private configuration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(CONFIGURATION_SECTION); private codeCounter_: LineCounterTable|null = null; private statusBarItem: vscode.StatusBarItem|null = null; private outputChannel: vscode.OutputChannel|null = null; @@ -82,77 +84,79 @@ class CodeCounterController { if (this.codeCounter_) { return this.codeCounter_ } - // const langs = new Map();//Object.entries(configuration.get<{[key:string]:VscodeLanguageConf}>('languages', {}))); - const langs = await loadLanguageExtensions(new Map()); - log(`loadLang = ${langs.size}`); - const confFiles = vscode.workspace.getConfiguration("files", null); - this.codeCounter_ = new LineCounterTable(langs, Object.entries(confFiles.get<{[key:string]:string}>('associations', {}))); - this.configuration.update('languages', objectFromEntries(langs), vscode.ConfigurationTarget.Global); + const langs = await loadLanguageConfigurations(); + log(`load Language Settings = ${langs.size}`); + await collectLanguageConfigurations(langs); + log(`collect Language Settings = ${langs.size}`); + const filesConf = vscode.workspace.getConfiguration("files", null); + this.codeCounter_ = new LineCounterTable(langs, Object.entries(filesConf.get<{[key:string]:string}>('associations', {}))); + //this.saveLanguageConfigurations(langs); return this.codeCounter_; } - public toggleVisible() { - if (!this.statusBarItem) { - this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); - this.countFile(vscode.window.activeTextEditor?.document); - } else { - this.statusBarItem.dispose(); - this.statusBarItem = null; - } + public saveLanguageConfigurations() { + this.getCodeCounter() + .then(c => saveLanguageConfigurations(c.entries())) + .catch(reason => showError(`saveLanguageConfigurations() failed.`, reason)); } + public outputAvailableLanguages() { this.getCodeCounter().then(c => { c.entries().forEach((lang, id) => { this.toOutputChannel(`${id} : aliases[${lang.aliases}], extensions[${lang.extensions}], filenames:[${lang.filenames}]`); }); this.toOutputChannel(`VS Code Counter : available all ${c.entries().size} languages.`); - }); + }) + .catch(reason => showError(`outputAvailableLanguages() failed.`, reason)); } - public countInDirectory(targetDir: vscode.Uri|undefined) { + + public async countInDirectory(targetDir: vscode.Uri|undefined) { try { - const folders = workspaceFolders(); - if (folders.length <= 0) { - vscode.window.showErrorMessage(`[${EXTENSION_NAME}] No open workspace`); - } else if (targetDir !== undefined) { - this.countLinesInDirectory(targetDir, folders[0].uri); + const folder = await currentWorkspaceFolder(); + if (!folder) { + showError(`No open workspace`); + } else if (targetDir) { + this.countLinesInDirectory(targetDir, folder.uri); } else { const option = { - value : folders[0].uri.toString(true), + value : folder.uri.toString(true), placeHolder: "Input Directory Path", prompt: "Input Directory Path. " }; - vscode.window.showInputBox(option).then(uri => { - if (uri) { - this.countLinesInDirectory(vscode.Uri.parse(uri), folders[0].uri); - } - }); + const uri = await vscode.window.showInputBox(option); + if (uri) { + this.countLinesInDirectory(vscode.Uri.parse(uri), folder.uri); + } } } catch (e) { - vscode.window.showErrorMessage(`[${EXTENSION_NAME}] countInDirectory() failed.`, e.message); + showError(`countInDirectory() failed.`, e.message); } } - public countInWorkspace() { + public async countInWorkspace() { try { - const folders = workspaceFolders(); - if (folders.length <= 0) { - vscode.window.showErrorMessage(`[${EXTENSION_NAME}] No open workspace`); - } else if (folders.length === 1) { - this.countLinesInDirectory(folders[0].uri, folders[0].uri); + const folder = await currentWorkspaceFolder(); + if (folder) { + this.countLinesInDirectory(folder.uri, folder.uri); } else { - vscode.window.showWorkspaceFolderPick().then((folder) => { - if (folder) { - this.countLinesInDirectory(folder.uri, folder.uri); - } - }); + showError(`No folder are open.`); } } catch (e) { - vscode.window.showErrorMessage(`[${EXTENSION_NAME}] countInWorkspace() failed.`, e.message); + showError(`countInWorkspace() failed.`, e.message); } } + private countLinesInDirectory(targetUri: vscode.Uri, workspaceDir: vscode.Uri) { + const conf = vscode.workspace.getConfiguration(CONFIGURATION_SECTION); + const outputDir = buildUri(workspaceDir, conf.get('outputDirectory', '.VSCodeCounter')); + this.getCodeCounter() + .then(c => countLinesInDirectory(c, targetUri, outputDir, conf, this.toOutputChannel)) + .then(results => outputResults(targetUri, results, outputDir, conf)) + .catch(reason => showError(`countLinesInDirectory() failed.`, reason)); + } + private onDidChangeWorkspaceFolders(e: vscode.WorkspaceFoldersChangeEvent) { log(`onDidChangeWorkspaceFolders()`); - e.added.forEach((f) => log(` added [${f.index}] ${f.name} : ${f.uri}`)); - e.removed.forEach((f) => log(` removed [${f.index}] ${f.name} : ${f.uri}`)); - workspaceFolders().forEach((f) => log(` [${f.index}] ${f.name} : ${f.uri}`)); + // e.added.forEach((f) => log(` added [${f.index}] ${f.name} : ${f.uri}`)); + // e.removed.forEach((f) => log(` removed [${f.index}] ${f.name} : ${f.uri}`)); + // vscode.workspace.workspaceFolders?.forEach((f) => log(` [${f.index}] ${f.name} : ${f.uri}`)); } private onDidChangeActiveTextEditor(e: vscode.TextEditor|undefined) { if (this.codeCounter_) { @@ -167,19 +171,20 @@ class CodeCounterController { } } private onDidChangeConfiguration() { - const newConf = vscode.workspace.getConfiguration(CONFIGURATION_SECTION); - if (JSON.stringify(this.configuration) !== JSON.stringify(newConf)) { - log(`onDidChangeConfiguration()`); - this.configuration = newConf; - this.codeCounter_ = null; + log(`onDidChangeConfiguration()`); + this.codeCounter_ = null; + this.countFile(vscode.window.activeTextEditor?.document); + } + + public toggleVisible() { + if (!this.statusBarItem) { + this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); this.countFile(vscode.window.activeTextEditor?.document); + } else { + this.statusBarItem.dispose(); + this.statusBarItem = null; } } - private countLinesInDirectory(targetUri: vscode.Uri, outputDirUri: vscode.Uri) { - this.getCodeCounter().then(c => { - countLinesInDirectory(c, targetUri, outputDirUri, this.configuration, this.toOutputChannel); - }); - } private showStatusBar(text: string) { if (this.statusBarItem) { this.statusBarItem.show(); @@ -264,7 +269,7 @@ const buildUri = (uri: vscode.Uri, filename: string) => uri.with({path: `${uri.p const dirUri = (uri: vscode.Uri) => uri.with({path: path.dirname(uri.path)}); function readFileAll(fileUris: vscode.Uri[]) : Promise<{uri:vscode.Uri, data:Uint8Array|null, error?:any}[]> { - const ret = new Array<{uri:vscode.Uri, data:Uint8Array|null, error?:any}>(); + const ret: {uri:vscode.Uri, data:Uint8Array|null, error?:any}[] = []; return new Promise((resolve: (values: {uri:vscode.Uri, data:Uint8Array|null, error?:any}[])=> void, reject: (reason: any) => void) => { if (fileUris.length > 0) { fileUris.forEach(fileUri => { @@ -288,9 +293,8 @@ function readFileAll(fileUris: vscode.Uri[]) : Promise<{uri:vscode.Uri, data:Uin } }); } -function countLinesInDirectory(lineCounterTable: LineCounterTable, targetUri: vscode.Uri, outputDirUri: vscode.Uri, configuration: vscode.WorkspaceConfiguration, consoleOut:(text:string)=>void) { - const outputDir = buildUri(outputDirUri, configuration.get('outputDirectory', '.VSCodeCounter')); - log(`countLinesInDirectory : ${targetUri}, output dir: ${outputDir}`); +function countLinesInDirectory(lineCounterTable: LineCounterTable, targetUri: vscode.Uri, outputDir: vscode.Uri, configuration: vscode.WorkspaceConfiguration, consoleOut:(text:string)=>void) { + log(`countLinesInDirectory : ${targetUri}, output dir: ${outputDir.fsPath}`); const confFiles = vscode.workspace.getConfiguration("files", null); const includes = configuration.get('include', ['**/*']); const excludes = configuration.get('exclude', []); @@ -305,7 +309,7 @@ function countLinesInDirectory(lineCounterTable: LineCounterTable, targetUri: vs log(`includes : "${includes.join('", "')}"`); log(`excludes : "${excludes.join('", "')}"`); - new Promise((resolve: (p: vscode.Uri[])=> void, reject: (reason: any) => void) => { + return new Promise((resolve: (p: vscode.Uri[])=> void, reject: (reason: any) => void) => { vscode.workspace.findFiles(`{${includes.join(',')}}`, `{${excludes.join(',')}}`).then((files: vscode.Uri[]) => { const fileUris = files.filter(uri => uri.path.startsWith(targetUri.path)); if (configuration.get('useGitignore', true)) { @@ -318,9 +322,6 @@ function countLinesInDirectory(lineCounterTable: LineCounterTable, targetUri: vs }, reject ); - // const t = .map(p => vscode.workspace.fs.readFile(p)); - // const gitignores = new Gitignore('').merge(...gitignoreFiles.map(uri => uri.fsPath).sort().map(p => new Gitignore(fs.readFileSync(p, 'utf8'), path.dirname(p)))); - // resolve(fileUris.filter(p => gitignores.excludes(p.fsPath))); }, reject ); @@ -367,30 +368,33 @@ function countLinesInDirectory(lineCounterTable: LineCounterTable, targetUri: vs } }); }); - }).then((results: Result[]) => { - outputResults(targetUri, results, outputDir, configuration); - }).catch((reason: string) => { - vscode.window.showErrorMessage(`[${EXTENSION_NAME}] countLinesInDirectory() failed.`, reason); }); } -type VscodeLang = { - id:string - aliases?:string[] - filenames?:string[] - extensions?:string[] - configuration?:string +type VscodeLanguage = { + id: string + aliases?: string[] + filenames?: string[] + extensions?: string[] + configuration?: string }; -type VscodeLanguageConf = { - aliases:string[] - filenames:string[] - extensions:string[] +type LanguageConf = { + aliases: string[] + filenames: string[] + extensions: string[] lineComments: string[] blockComments: [string,string][] blockStrings: [string,string][] } -const append = (langExtTable: Map, l:VscodeLang) => { - const langExt = getOrSet(langExtTable, l.id, ():VscodeLanguageConf => { +function pushUnique(array: T[], ...values: T[]) { + values.forEach(value => { + if (array.indexOf(value) < 0) { + array.push(value); + } + }); +} +const append = (langs: Map, l:VscodeLanguage) => { + const langExt = getOrSet(langs, l.id, ():LanguageConf => { return { aliases:[], filenames:[], @@ -400,26 +404,29 @@ const append = (langExtTable: Map, l:VscodeLang) => blockStrings:[] } }); - langExt.aliases.push(...(l.aliases??[])); - langExt.filenames.push(...(l.filenames??[])); - langExt.extensions.push(...(l.extensions??[])); + // l.aliases?.filter(v => langExt.aliases.indexOf(v) < 0).forEach(v => langExt.aliases.push(v)); + // l.filenames?.filter(v => langExt.filenames.indexOf(v) < 0).forEach(v => langExt.filenames.push(v)); + // l.extensions?.filter(v => langExt.extensions.indexOf(v) < 0).forEach(v => langExt.extensions.push(v)); + pushUnique(langExt.aliases, ...(l.aliases??[])); + pushUnique(langExt.filenames, ...(l.filenames??[])); + pushUnique(langExt.extensions, ...(l.extensions??[])); return langExt; } -function loadLanguageExtensions(langExtTable: Map) : Promise> { - return new Promise((resolve: (values: Map)=> void, reject: (reason: any) => void) => { +function collectLanguageConfigurations(langs: Map) : Promise> { + return new Promise((resolve: (values: Map)=> void, reject: (reason: any) => void) => { if (vscode.extensions.all.length <= 0) { - resolve(langExtTable); + resolve(langs); } else { let finishedCount = 0; let totalCount = 0; const decoderU8 = new TextDecoder('utf8'); vscode.extensions.all.forEach(ex => { - const languages = ex.packageJSON.contributes?.languages as Array ?? undefined; + const languages = ex.packageJSON.contributes?.languages as VscodeLanguage[] ?? undefined; if (languages) { totalCount += languages.length languages.forEach(l => { - const langExt = append(langExtTable, l); + const langExt = append(langs, l); if (l.configuration) { const confUrl = vscode.Uri.file(path.join(ex.extensionPath, l.configuration)); vscode.workspace.fs.readFile(confUrl).then(data => { @@ -427,26 +434,26 @@ function loadLanguageExtensions(langExtTable: Map) : const langConf = JSONC.parse(decoderU8.decode(data)) as vscode.LanguageConfiguration; if (langConf.comments) { if (langConf.comments.lineComment) { - langExt.lineComments.push(langConf.comments.lineComment); + pushUnique(langExt.lineComments, langConf.comments.lineComment); } if (langConf.comments.blockComment && langConf.comments.blockComment.length >= 2) { - langExt.blockComments.push(langConf.comments.blockComment); + pushUnique(langExt.blockComments, langConf.comments.blockComment); } } if (++finishedCount >= totalCount) { - resolve(langExtTable); + resolve(langs); } }, (reason:any) => { log(`${confUrl} : error ${reason}`); if (++finishedCount >= totalCount) { - resolve(langExtTable); + resolve(langs); } }); } else { if (++finishedCount >= totalCount) { - resolve(langExtTable); + resolve(langs); } } }); @@ -455,16 +462,57 @@ function loadLanguageExtensions(langExtTable: Map) : } }); } - +function saveLanguageConfigurations_(langs: {[key:string]:LanguageConf}) { + const conf = vscode.workspace.getConfiguration(CONFIGURATION_SECTION); + const saveLocation = conf.get('saveLocation', 'global settings'); + if (saveLocation === "global settings") { + conf.update('languages', langs, vscode.ConfigurationTarget.Global); + } else if (saveLocation === "workspace settings") { + conf.update('languages', langs, vscode.ConfigurationTarget.Workspace); + } else if (saveLocation === "output directory") { + currentWorkspaceFolder().then(async (folder) => { + if (!folder) return; + const outputDirUri = buildUri(folder.uri, conf.get('outputDirectory', '.VSCodeCounter')); + const uri = buildUri(outputDirUri, 'languages.json'); + await makeDirectories(outputDirUri); + writeTextFile(uri, JSON.stringify(langs)); + }); + } +} +function saveLanguageConfigurations(langs: Map) { + saveLanguageConfigurations_(mapToObject(langs)); +} +async function loadLanguageConfigurations_() { + const conf = vscode.workspace.getConfiguration(CONFIGURATION_SECTION); + const saveLocation = conf.get('saveLocation', 'global settings'); + if (saveLocation === "global settings") { + return conf.get<{[key:string]:LanguageConf}>('languages', {}); + } else if (saveLocation === "workspace settings") { + return conf.get<{[key:string]:LanguageConf}>('languages', {}); + } else if (saveLocation === "output directory") { + const workFolder = await currentWorkspaceFolder(); + if (!workFolder) return {}; + const outputDirUri = buildUri(workFolder.uri, conf.get('outputDirectory', '.VSCodeCounter')); + const uri = buildUri(outputDirUri, 'languages.json'); + const data = await vscode.workspace.fs.readFile(uri); + const decoderU8 = new TextDecoder('utf8'); + return JSONC.parse(decoderU8.decode(data)) as {[key:string]:LanguageConf}; + } else { + return {}; + } +} +async function loadLanguageConfigurations() { + return objectToMap(await loadLanguageConfigurations_()); +} class LineCounterTable { - private langExtensions: Map; + private langExtensions: Map; private langIdTable: Map; private aliasTable: Map; private fileextRules: Map; private filenameRules: Map; private associations: [string, string][]; - constructor(langExtensions: Map, associations: [string, string][]) { + constructor(langExtensions: Map, associations: [string, string][]) { this.langExtensions = langExtensions; this.langIdTable = new Map(); this.aliasTable = new Map(); @@ -504,7 +552,7 @@ async function outputResults(workspaceUri: vscode.Uri, results: Result[], output const endOfLine = conf.get('endOfLine', '\n'); log(`count ${results.length} files`); if (results.length <= 0) { - vscode.window.showErrorMessage(`[${EXTENSION_NAME}] There was no target file.`); + showError(`There was no target file.`); return; } const previewType = conf.get('outputPreviewType', ''); @@ -514,18 +562,18 @@ async function outputResults(workspaceUri: vscode.Uri, results: Result[], output const resultsUri = buildUri(outputDirUri, 'results.txt'); const promise = writeTextFile(resultsUri, resultTable.toTextLines().join(endOfLine)); if (previewType === 'text') { - promise.then(() => showTextFile(resultsUri)).catch(err => console.error(err)); + promise.then(() => showTextFile(resultsUri)).catch(err => showError(`failed to output text.`, err)); } else { - promise.catch(err => console.error(err)); + promise.catch(err => showError(`failed to output text.`, err)); } } if (conf.get('outputAsCSV', true)) { const resultsUri = buildUri(outputDirUri, 'results.csv'); const promise = writeTextFile(resultsUri, resultTable.toCSVLines().join(endOfLine)); if (previewType === 'csv') { - promise.then(() => showTextFile(resultsUri)).catch(err => console.error(err)); + promise.then(() => showTextFile(resultsUri)).catch(err => showError(`failed to output csv.`, err)); } else { - promise.catch(err => console.error(err)); + promise.catch(err => showError(`failed to output csv.`, err)); } } if (conf.get('outputAsMarkdown', true)) { @@ -565,9 +613,9 @@ async function outputResults(workspaceUri: vscode.Uri, results: Result[], output ); if (previewType === 'markdown') { promise.then(() => vscode.commands.executeCommand("markdown.showPreview", resultsUri)) - .catch(err => console.error(err)); + .catch(err => showError(`failed to output markdown text.`, err)); } else { - promise.catch(err => console.error(err)); + promise.catch(err => showError(`failed to output markdown text.`, err)); } } } @@ -725,8 +773,6 @@ class ResultTable { const langFormat = new TextTableFormatter(this.valueToString, {title:'language', width:maxLanglen}, {title:'files', width:10}, {title:'code', width:10}, {title:'comment', width:10}, {title:'blank', width:10}, {title:'total', width:10}); return [ - // '='.repeat(resultFormat.headerLines[0].length), - // EXTENSION_NAME, `Date : ${dateToString(new Date())}`, `Directory : ${this.targetDirPath}`, // `Total : code: ${this.total.code}, comment : ${this.total.comment}, blank : ${this.total.blank}, all ${this.total.total} lines`, @@ -810,13 +856,17 @@ class ResultTable { } -function objectFromEntries(map: Map) { +function mapToObject(map: Map) { const obj: any = {} map.forEach((v,id)=>{ obj[id] = v }) return obj; } +function objectToMap(obj: {[key: string]: V}): Map { + return new Map(Object.entries(obj)); +} + function getOrSet(map: Map, key: K, otherwise: () => V) { let v = map.get(key); if (v === undefined) { @@ -828,10 +878,10 @@ function getOrSet(map: Map, key: K, otherwise: () => V) { function makeDirectories_(dirpath: vscode.Uri, resolve: ()=> void, reject: (reason: string) => void) { // log(`makeDirectories ${dirpath}`); vscode.workspace.fs.stat(dirpath).then((value) => { - if (value.type !== vscode.FileType.File) { - resolve(); - } else { + if (value.type === vscode.FileType.File) { reject(`${dirpath} is not directory.`); + } else { + resolve(); } }, (reason) => { log(`vscode.workspace.fs.stat failed: ${reason}`); From e658cec043d2d0b4ebe004a76fe586456d3c9b25 Mon Sep 17 00:00:00 2001 From: uctakeoff Date: Sat, 4 Jul 2020 21:58:53 +0900 Subject: [PATCH 3/3] Update: documents. --- CHANGELOG.md | 11 +++++++++++ README.md | 27 +++++++++++++++++++++++++-- images/save_lang.png | Bin 0 -> 25567 bytes package-lock.json | 8 ++++---- package.json | 2 +- 5 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 images/save_lang.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 618d0a4..726b735 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how * workspace counter in status bar. +## [2.0.0] + +### Added + +- New Command : `Save the collected language configurations`. + +### Update + +- This extension is no longer resident. + - Don't save whether or not the program is shown in the status bar in the settings. + ## [1.3.5] ### Fixed diff --git a/README.md b/README.md index 61e35fa..4f4af11 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,13 @@ VS Code extension: counts blank lines, comment lines, and physical lines of sour * [github](https://github.com/uctakeoff/vscode-counter) * [Marketplace](https://marketplace.visualstudio.com/items?itemName=uctakeoff.vscode-counter) +## VSCode Counter 2.0 is released! + +* Experimental support for "**VSCode Remove Development**". + + When using VSCode Counter in *VSCode Remove Development*, use the `Save language configurations` function You will need to. + [See below for more information](#save-language-configurations). + ## Features - Count the code lines of source code in workspace or directory. @@ -41,9 +48,25 @@ VS Code extension: counts blank lines, comment lines, and physical lines of sour * Available languages can be increased by adding language extensions. +### Save language configurations + +**VSCode Counter** is able to aggregate in unknown languages by referring to the information in the installed language extensions. However, I found out that **this information is not available in Remote Development**. + +Therefore, VSCode Counter's ability of **collecting VSCode language extensions** is now called as an independent function. The idea is to collect the information once in the local environment and store it so that it can be used remotely. + +* First, launch VSCode on your local server. +* Then, open the command palette and select `VSCodeCounter: Save the collected language configurations`. +* Then *settings.json* will store the configuration information collected from the current language extensions . + ![](images/save_lang.png) +* Connect to the remote and use the VSCodecounter as usual. + + +You can also change the location where your configurations are stored. +However, you must carry the stored information to the remote environment by yourself. + + ## Extension Settings -* `VSCodeCounter.showInStatusBar`: Whether to show the count result of the current file on the status bar in real time. * `VSCodeCounter.useGitignore`: Whether to use '.gitignore' files for excluding files. * `VSCodeCounter.useFilesExclude`: Whether to use setting 'files.exclude' for excluding files. * `VSCodeCounter.printNumberWithCommas`: Whether to print a number with commas as thousands separators.(except for CSV) @@ -56,6 +79,6 @@ VS Code extension: counts blank lines, comment lines, and physical lines of sour * `VSCodeCounter.outputAsCSV`: Whether to output the result as a CSV file. * `VSCodeCounter.outputAsMarkdown`: Whether to output the result as a Markdown file. * `VSCodeCounter.outputPreviewType`: Type of output file to preview after counting. Choose from `text`, `csv`, `markdown` or `none`. -* `VSCodeCounter.blockComment`: Define patterns indicating the beginning and end of the block document(here document). +* `VSCodeCounter.saveLocation`: Specify where to store the collected language configurations. **Enjoy!** diff --git a/images/save_lang.png b/images/save_lang.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc82ed0557beb596aabae7651078091c89d5135 GIT binary patch literal 25567 zcmb@ubyQVr+cmxjK|nx2K^jp&X$k348Uc}R6bXS%cPk(bA_CGS-Q6WA-Cfe%o!`Cj zocBEE8Sih5-}uJ&hhuDataYzDu4`U%&I{kyGGdtMMCcF%VM>S#zkwjcXz~RlsDM{)DbNc7LFa2N({+{oUs&c(uqu<;% zeh@@`#dKjq#zgvel;QjEeiuxQ6L&Qd|B1Q4MwgxBFb0+6!ZoTJGr@?~`Iz+=Z{yA8OXpRB z>-5Xk>pYZ>WhVo2hXri`ZpS$~w`HYuPr_|GYPW~A7AiJN*Kw{(_2gGuCSBLuJ7ZP# z$KCvUn>|0hv96!FY?R5S*Lh!Ct?ZCns2s9THw#^D#0Ce&Js}|%?CLNZa{WdoV1~RK zFq3n-5HIh2eR%0Ie0^ama~%~i^X6ij?8;l)FZTCk_X5)oPJ>#P7gMR%l9YG(52B+! zA$@GjWL3Xz?AsfwS`DY1cU#<^)Na%{A$LW)0GB!6_20PS8rci0v&ypZNkyf@WzJ}2GzLhB`^6a2Len`2g=emKbMIf7de~M@_%6X~2)8x8+?RszWDwXNV zU_|xWgb≫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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 4dd9281..da1bd9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vscode-counter", - "version": "1.3.5", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -701,9 +701,9 @@ } }, "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.0.tgz", + "integrity": "sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA==" }, "locate-path": { "version": "5.0.0", diff --git a/package.json b/package.json index f9314f5..f1b276b 100644 --- a/package.json +++ b/package.json @@ -272,7 +272,7 @@ "vscode-test": "^1.4.0" }, "dependencies": { - "jsonc-parser": "^2.2.1", + "jsonc-parser": "^2.3.0", "minimatch": "^3.0.4" } }