Asper Header  1.0.16
The header injector extension
Loading...
Searching...
No Matches
commentGenerator.ts
Go to the documentation of this file.
1
59import * as vscode from 'vscode';
60import { minimatch } from 'minimatch';
61import { CodeConfig, CodeConfigType } from './processConfiguration';
62import { query } from './querier';
63import { logger } from './logger';
64import { getMessage } from './messageProvider';
65import { LazyFileLoader } from './lazyFileLoad';
66import { RandomLogo, logo } from './randomLogo';
67
75interface CommentStyle {
77 singleLine: string[];
79 multiLine: string[];
81 prompt_comment_opening_type: boolean;
83 language?: string;
84}
85
137export class CommentGenerator {
139 private Config: CodeConfigType = CodeConfig;
141 private randomLogo: RandomLogo = new RandomLogo();
143 private languageComment: LazyFileLoader | undefined = undefined;
145 private documentBody: vscode.TextDocument | undefined = undefined;
147 private filePath: string | undefined = undefined;
149 private fileName: string | undefined = undefined;
151 private fileExtension: string | undefined = undefined;
153 private languageId: string | undefined = undefined;
155 private documentEOL: vscode.EndOfLine | undefined = undefined;
157 private documentVersion: number | undefined = undefined;
159 private headerInnerStart: number | undefined = undefined;
161 private headerInnerEnd: number | undefined = undefined;
163 private maxScanLength: number = this.Config.get("maxScanLength");
165 private headerLogo: string[] = this.Config.get("headerLogo");
167 private projectName: string = this.Config.get("extensionName");
169 private projectCopyRight: string = this.Config.get("projectCopyright");
171 private addBlankLineAfterMultiline: boolean = this.Config.get("headerAddBlankLineAfterMultiline");
173 private languagePrepend: Record<string, string> = this.Config.get("languagePrepend");
175 private languageAppend: Record<string, string> = this.Config.get("languageAppend");
177 private singleLineOverride: Record<string, string> = this.Config.get("languageSingleLineComment");
179 private multiLineOverride: Record<string, string[]> = this.Config.get("languageMultiLineComment");
181 private trimTrailingSpaces: boolean = this.Config.get("removeTrailingHeaderSpaces");
183 private preferSingleLineComments: boolean = this.Config.get("preferSingleLineComments");
184
194 constructor(languageComment: LazyFileLoader | undefined = undefined, editor: vscode.TextEditor | undefined = undefined, randomLogoInstance: RandomLogo | undefined = undefined) {
195 logger.debug(getMessage("inFunction", "constructor", "CommentGenerator"));
196 if (languageComment !== undefined) {
197 this.languageComment = languageComment;
198 logger.debug(getMessage("foundLanguageComment"));
199 } else {
200 logger.warning(getMessage("missingLanguageComment"));
201 }
202 if (!editor) {
203 logger.warning(getMessage("noFocusedEditors"));
204 } else {
205 this.updateFileInfo(editor.document);
206 logger.debug(getMessage("foundFocusEditor"));
207 }
208 if (!randomLogoInstance) {
209 logger.warning(getMessage("noLogoInstanceProvided"));
210 } else {
211 this.randomLogo = randomLogoInstance;
212 logger.debug(getMessage("foundLogoInstance"));
213 }
214 }
215
224 private determineNewLine(eol: vscode.EndOfLine): string {
225 logger.debug(getMessage("inFunction", "determineNewLine", "CommentGenerator"));
226 if (eol === vscode.EndOfLine.LF) {
227 logger.debug(getMessage("foundNewLine", "\\n"));
228 return "\n";
229 } else {
230 logger.debug(getMessage("foundNewLine", "\\r\\n"));
231 return "\r\n";
232 }
233 }
234
245 private headerOpener(comment: string, eol: vscode.EndOfLine, projectName: string = this.Config.get("extensionName")): string {
246 logger.debug(getMessage("inFunction", "headerOpener", "CommentGenerator"));
247 let final: string = comment + this.Config.get("headerOpenerDecorationOpen");
248 final += this.Config.get("telegraphBegin") + " ";
249 final += projectName;
250 final += this.Config.get("headerOpenerDecorationClose");
251 final += this.determineNewLine(eol);
252 return final;
253 }
254
263 private async determineCorrectComment(): Promise<CommentStyle> {
264 logger.debug(getMessage("inFunction", "determineCorrectComment", "CommentGenerator"));
265 const primaryKey: string = "langs";
266 let commentStructure: CommentStyle = {
267 singleLine: [],
268 multiLine: [],
269 prompt_comment_opening_type: false,
270 language: undefined,
271 };
272 if (this.languageComment === undefined) {
273 logger.Gui.error(getMessage("missingFileError"));
274 return commentStructure;
275 }
276 const jsonContent = await this.languageComment?.get();
277 // logger.info(getMessage("jsonContent", JSON.stringify(jsonContent)));
278 if (!jsonContent || typeof jsonContent !== 'object' || jsonContent === null || (primaryKey in jsonContent) === false) {
279 logger.Gui.error(getMessage("unknownFileStructure"));
280 return commentStructure;
281 }
282 if (Array.isArray(jsonContent[primaryKey]) === false) {
283 logger.Gui.error(getMessage("unknownFileStructure"));
284 return commentStructure;
285 }
286 let index = 0;
287 const languageNodes = jsonContent[primaryKey];
288 let locatedName: string = "";
289 for (; index < languageNodes.length; index++) {
290 let nodeFound = false;
291 const node = languageNodes[index];
292
293 const nodeLangs: string[] = node.langs ?? [];
294 const nodeFileExtensions: Record<string, string[]> = node.fileExtensions ?? {};
295
296 for (let langIndex = 0; langIndex < nodeLangs.length; langIndex++) {
297 const langName = nodeLangs[langIndex].toLowerCase();
298 locatedName = langName;
299
300 if (langName === this.languageId?.toLowerCase()) {
301 nodeFound = true;
302 break;
303 }
304
305 if (this.fileExtension) {
306 const extensionsForLang = nodeFileExtensions[langName] ?? [];
307 for (let extIndex = 0; extIndex < extensionsForLang.length; extIndex++) {
308 let dot: string = "";
309 if (extensionsForLang[extIndex].length > 0 && extensionsForLang[extIndex][0] === ".") {
310 dot = ".";
311 }
312 if (extensionsForLang[extIndex] === `${dot}${this.fileExtension}`) {
313 nodeFound = true;
314 break;
315 }
316 }
317 }
318
319 if (nodeFound) {
320 break;
321 }
322 }
323
324 logger.debug(getMessage("arrayNodeContent", `Json[${primaryKey}]`, index, node));
325 if (nodeFound) {
326 logger.Gui.info(getMessage("identifiedLanguage", locatedName));
327 logger.info(getMessage("arrayNodeContent", `Json[${primaryKey}]`, index, node));
328 commentStructure.singleLine = node.singleLine ?? [];
329 commentStructure.multiLine = node.multiLine ?? [];
330 commentStructure.prompt_comment_opening_type = node.prompt_comment_opening_type ?? false;
331 commentStructure.language = locatedName ?? undefined;
332 return commentStructure;
333 }
334 }
335 logger.error(getMessage("languageNotFound", String(this.languageId), this.fileExtension));
336 return commentStructure;
337 }
338
346 private async determineHeaderDescription(): Promise<string[]> {
347 logger.debug(getMessage("inFunction", "determineHeaderDescription", "CommentGenerator"));
348 const rawAny = this.Config.get("projectDescription");
349 let intermediate: string = "";
350 if (Array.isArray(rawAny)) {
351 intermediate = rawAny.join(this.determineNewLine(this.documentEOL || vscode.EndOfLine.LF));
352 } else {
353 intermediate = String(rawAny ?? "");
354 }
355 if (intermediate.trim().length === 0) {
356 const usrResponse: string | undefined = await query.input(getMessage("getHeaderDescription"));
357 intermediate = (usrResponse || "");
358 } else {
359 logger.debug(getMessage("configDescriptionUsed"));
360 }
361 const final = intermediate.split(/\r?\n/);
362 return final;
363 }
364
372 private async determineHeaderTags(): Promise<string[]> {
373 logger.debug(getMessage("inFunction", "determineHeaderTags", "CommentGenerator"));
374 let final: string[] = [];
375 const usrResponse: string | undefined = await query.input(getMessage("getHeaderTags"));
376 final.push(usrResponse || "");
377 return final;
378 }
379
387 private async determineHeaderPurpose(): Promise<string[]> {
388 logger.debug(getMessage("inFunction", "determineHeaderPurpose", "CommentGenerator"));
389 let final: string[] = [];
390 const usrResponse: string | undefined = await query.input(getMessage("getHeaderPurpose"));
391 final.push(usrResponse || "");
392 return final;
393 }
394
405 private async getSingleCommentOption(commentOptions: string[]): Promise<string> {
406 logger.debug(getMessage("inFunction", "getSingleCommentOption", "CommentGenerator"));
407 if (commentOptions.length === 0) {
408 logger.Gui.error(getMessage("noCommentToShow"));
409 throw Error(getMessage("noCommentToShow"));
410 }
411 if (commentOptions.length === 1) {
412 logger.info(getMessage("noProvidedCommentOptions"));
413 return commentOptions[0];
414 }
415 const response: string | undefined = await query.quickPick(commentOptions, getMessage("chooseSingleLineCommentOption"));
416 return response || commentOptions[0];
417 }
418
426 private addKeyDefinitionSeparator(): string {
427 logger.debug(getMessage("inFunction", "addKeyDefinitionSeparator", "CommentGenerator"));
428 const userSettingDefinedElement: string = this.Config.get("headerKeyDefinitionSeparator");
429 return userSettingDefinedElement || this.Config.get("headerKeyDefinitionSeparator");
430 }
431
441 private addCreationDate(comment: string, eol: vscode.EndOfLine) {
442 logger.debug(getMessage("inFunction", "addCreationDate", "CommentGenerator"));
443 const now = new Date();
444 const day = String(now.getDate()).padStart(2, "0");
445 const month = String(now.getMonth() + 1).padStart(2, "0"); // Months are 0-based
446 const year = now.getFullYear();
447 const separatorDay: string = this.Config.get("headerDateSeperatorDay");
448 const separatorMonth: string = this.Config.get("headerDateSeperatorMonth");
449 const separatorYear: string = this.Config.get("headerDateSeperatorYear");
450 let final: string = comment + this.Config.get("headerCreationDateKey") + this.addKeyDefinitionSeparator();
451 final += `${day}${separatorDay}${month}${separatorMonth}${year}${separatorYear}`;
452 final += this.determineNewLine(eol);
453 return final;
454 }
455
466 private addLastModifiedDate(comment: string, eol: vscode.EndOfLine) {
467 logger.debug(getMessage("inFunction", "addLastModifiedDate", "CommentGenerator"));
468 const now: Date = new Date();
469 const day: string = String(now.getDate()).padStart(2, "0");
470 const month: string = String(now.getMonth() + 1).padStart(2, "0"); // Months are 0-based
471 const year: number = now.getFullYear();
472 const hour: number = now.getHours();
473 const minute: number = now.getMinutes();
474 const seconds: number = now.getSeconds();
475 const separatorDay: string = this.Config.get("headerDateSeperatorDay");
476 const separatorMonth: string = this.Config.get("headerDateSeperatorMonth");
477 const separatorYear: string = this.Config.get("headerDateSeperatorYear");
478 const separatorTimeAndDate: string = this.Config.get("headerTimeAndDateSeperator");
479 const separatorSecond: string = this.Config.get("headerTimeSeperatorSecond");
480 const separatorMinute: string = this.Config.get("headerTimeSeperatorMinute");
481 const separatorHour: string = this.Config.get("headerTimeSeperatorHour");
482 let final: string = comment + this.Config.get("headerLastModifiedKey") + this.addKeyDefinitionSeparator();
483 final += `${hour}${separatorHour}${minute}${separatorMinute}${seconds}${separatorSecond}${separatorTimeAndDate}${day}${separatorDay}${month}${separatorMonth}${year}${separatorYear}`;
484 final += this.determineNewLine(eol);
485 return final;
486 }
487
497 private mySmartTrimmer(content: string): string {
498 if (this.trimTrailingSpaces) {
499 return content.trimEnd();
500 }
501 return content;
502 }
503
516 private addMultilineKey(comment: string, eol: vscode.EndOfLine, tagName: string, tagDefinition: string[]): string {
517 logger.debug(getMessage("inFunction", "addMultilineKey", "CommentGenerator"));
518 const eolStr: string = this.determineNewLine(eol);
519 const keyLine: string = comment + tagName + this.mySmartTrimmer(this.addKeyDefinitionSeparator()) + eolStr;
520 let final: string = keyLine;
521 for (let i = 0; i < tagDefinition.length; i++) {
522 final += comment + tagDefinition[i] + eolStr;
523 }
524 final += comment + this.Config.get("telegraphBlockStop") + eolStr;
525 if (this.addBlankLineAfterMultiline) {
526 final += comment + eolStr;
527 }
528 return final;
529 }
530
541 private addSingleLineKey(comment: string, eol: vscode.EndOfLine, tagName: string, tagDefinition: string): string {
542 logger.debug(getMessage("inFunction", "addSingleLineKey", "CommentGenerator"));
543 let final: string = comment + tagName + this.addKeyDefinitionSeparator();
544 final += tagDefinition + this.determineNewLine(eol);
545 return final;
546 }
547
557 private beforeHeaderCloser(comment: string, eol: vscode.EndOfLine): string {
558 logger.debug(getMessage("inFunction", "beforeHeaderCloser", "CommentGenerator"));
559 return comment + this.Config.get("telegraphEndOfTransmission") + this.determineNewLine(eol);
560 }
561
572 private headerCloser(comment: string, eol: vscode.EndOfLine, projectName: string = this.Config.get("extensionName")): string {
573 logger.debug(getMessage("inFunction", "headerCloser", "CommentGenerator"));
574 let final: string = comment + this.Config.get("headerOpenerDecorationOpen");
575 final += this.Config.get("telegraphEnd") + " ";
576 final += projectName;
577 final += this.Config.get("headerOpenerDecorationClose");
578 final += this.determineNewLine(eol);
579 return final;
580 }
581
590 private updateFileInfo(document: vscode.TextDocument) {
591 logger.debug(getMessage("inFunction", "updateFileInfo", "CommentGenerator"));
592 this.headerInnerEnd = undefined;
593 this.headerInnerStart = undefined;
594 this.documentBody = document;
595 if (this.Config.get("useWorkspaceNameWhenAvailable")) {
596 this.projectName = this.Config.get("workspaceName") || this.Config.get("extensionName");
597 } else {
598 this.projectName = this.Config.get("extensionName");
599 }
600 this.filePath = this.documentBody.uri.fsPath;
601 this.projectCopyRight = this.Config.get("projectCopyright");
602 this.addBlankLineAfterMultiline = this.Config.get("headerAddBlankLineAfterMultiline");
603 this.maxScanLength = this.Config.get("defaultMaxScanLength") + this.headerLogo.length;
604 this.fileName = this.documentBody.uri.path.split('/').pop() || "unknown";
605 if (this.fileName.includes('.')) {
606 this.fileExtension = this.fileName.split('.').pop() || "none";
607 } else {
608 this.fileExtension = "none";
609 };
610 this.languageId = this.documentBody.languageId;
611 this.documentEOL = this.documentBody.eol;
612 this.documentVersion = this.documentBody.version;
613 }
614
631 private prependIfPresent(buildHeader: string[], eol: vscode.EndOfLine, languageId?: string): string[] {
632 if (languageId === undefined) {
633 return buildHeader;
634 }
635 const instance = this.languagePrepend[languageId];
636 if (instance !== undefined) {
637 let instanceCleaned: string = instance;
638 if (Array.isArray(instance)) {
639 instanceCleaned = instance.join(this.determineNewLine(eol));
640 }
641 buildHeader.push(instanceCleaned);
642 logger.debug(getMessage("languagePrependApplied", languageId, instanceCleaned));
643 }
644 return buildHeader;
645 }
646
664 private appendIfPresent(buildHeader: string[], eol: vscode.EndOfLine, languageId?: string): string[] {
665 if (languageId === undefined) {
666 return buildHeader;
667 }
668 const instance = this.languageAppend[languageId];
669 if (instance !== undefined) {
670 let instanceCleaned: string = instance;
671 if (Array.isArray(instance)) {
672 instanceCleaned = instance.join(this.determineNewLine(eol));
673 }
674 buildHeader.push(instanceCleaned);
675 logger.debug(getMessage("languageAppendApplied", languageId, instanceCleaned));
676 }
677 return buildHeader;
678 }
679
702 private getOverrideIfPresent(determinedComment: CommentStyle): CommentStyle {
703 // If the language is not known, nothing to override
704 if (!determinedComment.language) {
705 return determinedComment;
706 }
707
708 const languageId = determinedComment.language;
709
710 // Apply single-line override if present
711 const singleOverride = this.singleLineOverride[languageId];
712 if (singleOverride !== undefined) {
713 // Wrap the single string into an array since CommentStyle.singleLine expects string[]
714 if (Array.isArray(singleOverride)) {
715 determinedComment.singleLine = singleOverride;
716 } else {
717 determinedComment.singleLine = [singleOverride];
718 }
719 logger.debug(getMessage("singleLineCommentOverrideApplied", languageId, determinedComment.singleLine));
720 }
721
722 // Apply multi-line override if present
723 const multiOverride = this.multiLineOverride[languageId];
724 if (multiOverride !== undefined) {
725 // multiOverride is already a string[]
726 determinedComment.multiLine = multiOverride;
727 logger.debug(getMessage("multiLineCommentOverrideApplied", languageId, determinedComment.multiLine));
728 }
729
730 return determinedComment;
731 }
741 private async getCorrectCommentPrefix(determinedComment: CommentStyle): Promise<string[]> {
742 logger.debug(getMessage("inFunction", "getCorrectPrefix", "CommentGenerator"));
743 let commentOpener: string = "";
744 let commentMiddle: string = "";
745 let commentCloser: string = "";
746 const determinedComment_checked: CommentStyle = this.getOverrideIfPresent(determinedComment);
747 if (determinedComment_checked.multiLine.length >= 2 && this.preferSingleLineComments === false) {
748 commentOpener = determinedComment_checked.multiLine[0];
749 if (determinedComment_checked.multiLine.length >= 3) {
750 commentMiddle = determinedComment_checked.multiLine[1];
751 commentCloser = determinedComment_checked.multiLine[2];
752 } else {
753 commentMiddle = "";
754 commentCloser = determinedComment_checked.multiLine[1];
755 }
756 } else if (determinedComment_checked.singleLine.length > 0) {
757 if (determinedComment_checked.prompt_comment_opening_type) {
758 // Ask the user for the type to use based on the single comments that are present.
759 const commentString: string = await this.getSingleCommentOption(determinedComment_checked.singleLine);
760 commentOpener = commentString;
761 commentMiddle = commentString;
762 commentCloser = commentString;
763 } else {
764 commentOpener = determinedComment_checked.singleLine[0];
765 commentMiddle = determinedComment_checked.singleLine[0];
766 commentCloser = determinedComment_checked.singleLine[0];
767 }
768 } else {
769 commentOpener = "";
770 commentMiddle = "";
771 commentCloser = "";
772 }
773 commentOpener += this.Config.get("headerCommentSpacing");
774 commentMiddle += this.Config.get("headerCommentSpacing");
775 commentCloser += this.Config.get("headerCommentSpacing");
776 return [commentOpener, commentMiddle, commentCloser];
777 }
778
794 private async buildTheHeader(comments: string[], languageId?: string): Promise<string[]> {
795 logger.debug(getMessage("inFunction", "buildTheHeader", "CommentGenerator"));
796 const eol: vscode.EndOfLine = this.documentEOL || vscode.EndOfLine.LF;
797 const unknownTerm: string = getMessage("unknown");
798 const commentOpener: string = comments[0] || "";
799 const commentMiddle: string = comments[1] || "";
800 const commentCloser: string = comments[2] || "";
801 let buildHeader: string[] = [];
802 // Check wether there are elements required to be added before the header
803 buildHeader = this.prependIfPresent(buildHeader, eol, languageId);
804 // Preparing the header content so that it can be put in a comment and written.
805 if (commentOpener.length > 0) {
806 buildHeader.push(`${commentOpener}${this.determineNewLine(eol)}`);
807 }
808 // Opening the header
809 buildHeader.push(this.headerOpener(commentMiddle, eol, this.projectName));
810 // The logo
811 let logoContent = this.headerLogo;
812 if (this.Config.get("randomLogo") === true) {
813 try {
814 const gatheredLogo: logo = await this.randomLogo.getRandomLogoFromFolder();
815 if (gatheredLogo.logoContent !== undefined) {
816 logoContent = gatheredLogo.logoContent;
817 } else {
818 logger.error(getMessage("randomLogoGatheringFailed", getMessage("ramdomLogoGatheringLogoUndefined")));
819 }
820 } catch (e) {
821 logger.error(getMessage("randomLogoGatheringFailed", String(e)));
822 }
823 }
824 buildHeader.push(this.addMultilineKey(commentMiddle, eol, this.Config.get("headerLogoKey"), logoContent));
825 // The project name
826 buildHeader.push(this.addSingleLineKey(commentMiddle, eol, this.Config.get("headerProjectKey"), this.projectName));
827 // The file name
828 buildHeader.push(this.addSingleLineKey(commentMiddle, eol, this.Config.get("headerFileKey"), this.fileName || unknownTerm));
829 // The Creation date
830 buildHeader.push(this.addCreationDate(commentMiddle, eol));
831 // The Last modified date
832 buildHeader.push(this.addLastModifiedDate(commentMiddle, eol));
833 // The description
834 buildHeader.push(this.addMultilineKey(commentMiddle, eol, this.Config.get("headerDescriptionKey"), await this.determineHeaderDescription()));
835 // The copyright
836 buildHeader.push(this.addSingleLineKey(commentMiddle, eol, this.Config.get("headerCopyrightKey"), this.projectCopyRight));
837 // The Tag
838 // buildHeader.push(this.addSingleLineKey(commentMiddle, eol, this.Config.get("headerTagKey"), (await this.determineHeaderTags()).join(",")));
839 // The Purpose
840 buildHeader.push(this.addSingleLineKey(commentMiddle, eol, this.Config.get("headerPurposeKey"), (await this.determineHeaderPurpose()).join(";")));
841 // End of transmission telegraph
842 buildHeader.push(this.beforeHeaderCloser(commentMiddle, eol));
843 // Closing the header
844 buildHeader.push(this.headerCloser(commentMiddle, eol, this.projectName));
845 if (commentCloser.length > 0) {
846 buildHeader.push(`${commentCloser}${this.determineNewLine(eol)}`);
847 }
848 // Check wether there are elements required to be added after the header
849 buildHeader = this.appendIfPresent(buildHeader, eol, languageId);
850 return buildHeader;
851 }
852
862 private async updateEditDate(document: vscode.TextDocument, comments: string[]) {
863 logger.debug(getMessage("inFunction", "updateEditDate", "CommentGenerator"));
864 const commentOpener: string = comments[0] || "";
865 const commentMiddle: string = comments[1] || "";
866 const commentCloser: string = comments[2] || "";
867 if (this.headerInnerStart === undefined || this.headerInnerEnd === undefined) {
868 const errMsg: string = getMessage("updateEditDateMissingBounds");
869 logger.error(errMsg);
870 logger.Gui.error(errMsg);
871 return;
872 }
873 if (!this.documentBody) {
874 const errMsg: string = getMessage("emptyDocument");
875 logger.error(errMsg);
876 logger.Gui.error(errMsg);
877 return;
878 }
879
880 const eol = this.documentEOL || vscode.EndOfLine.LF;
881 const lastModifiedKey = this.Config.get("headerLastModifiedKey");
882
883 // Build the new "Last Modified" line
884 const newLine = this.addLastModifiedDate(commentMiddle, eol).trimEnd();
885
886 let targetLine: number | undefined = undefined;
887
888 // Scan header block to locate the "Last Modified" line
889 for (let i = this.headerInnerStart; i <= this.headerInnerEnd; i++) {
890 const lineText = this.documentBody.lineAt(i).text;
891 if (lineText.includes(lastModifiedKey)) {
892 targetLine = i;
893 break;
894 }
895 }
896
897 if (targetLine === undefined) {
898 const errMsg: string = getMessage("lastModifiedLineNotFound");
899 logger.error(errMsg);
900 logger.Gui.error(errMsg);
901 return;
902 }
903
904 const edit = new vscode.WorkspaceEdit();
905 const range = document.lineAt(targetLine).range;
906 edit.replace(document.uri, range, newLine);
907 await vscode.workspace.applyEdit(edit);
908
909 const msg: string = getMessage("lastModifiedUpdated");
910 logger.info(msg);
911 logger.Gui.info(msg);
912 }
913
923 protected locateIfHeaderPresent(comments: string[]): boolean | undefined {
924 logger.debug(getMessage("inFunction", "locateIfHeaderPresent", "CommentGenerator"));
925 const commentOpener: string = comments[0] || "";
926 const commentMiddle: string = comments[1] || "";
927 const commentCloser: string = comments[2] || "";
928 this.headerInnerStart = undefined;
929 this.headerInnerEnd = undefined;
930 if (this.documentBody === undefined) {
931 logger.error(getMessage("emptyDocument"));
932 return undefined;
933 }
934 if (this.documentBody.isClosed) {
935 logger.warning(getMessage("closedDocument"));
936 return undefined;
937 }
938 const documentTotalLines: number = this.documentBody.lineCount;
939 const eol: vscode.EndOfLine = this.documentEOL ?? vscode.EndOfLine.LF;
940 const opener: string = this.headerOpener(commentMiddle, eol, this.projectName).trimEnd();
941 const closer: string = this.headerCloser(commentMiddle, eol, this.projectName).trimEnd();
942 const scanLines: number = Math.min(this.maxScanLength, documentTotalLines);
943 const graceLines: number = Math.min((this.maxScanLength * 2), documentTotalLines);
944 let lineOpenerFound: boolean = false;
945 let lineCloserFound: boolean = false;
946 for (let i = 0; i < scanLines || (i < graceLines && lineOpenerFound && !lineCloserFound); i++) {
947 const lineText = this.documentBody.lineAt(i).text;
948 if (i >= scanLines) {
949 logger.info(getMessage("graceLines"));
950 }
951
952 // If we encounter a closer before any opener, the header is broken
953 if (lineText === closer && !lineOpenerFound) {
954 logger.Gui.warning(getMessage("brokenHeader"));
955 return false;
956 }
957
958 // If we encounter an opener after a closer was already found, header is broken
959 if (lineText === opener && lineCloserFound) {
960 logger.Gui.warning(getMessage("brokenHeader"));
961 return false;
962 }
963
964 // Detect opener
965 if (lineText === opener && !lineOpenerFound) {
966 lineOpenerFound = true;
967 this.headerInnerStart = i;
968 logger.info(getMessage("headerOpenerFound"));
969 continue;
970 }
971
972 // Detect closer (only valid if opener was already seen)
973 if (lineText === closer && !lineCloserFound) {
974 this.headerInnerEnd = i;
975 lineCloserFound = true;
976 }
977
978 if (lineCloserFound && lineOpenerFound) {
979 logger.info(getMessage("headerOpenerAndCloserFound"));
980 return true;
981 }
982 }
983 logger.Gui.warning(getMessage("documentLineScanExceeded", this.maxScanLength));
984 return false;
985 }
986
1002 private skipFirstLineInDocument(document: vscode.TextDocument): number {
1003 let insertLine = 0;
1004
1005 if (document.lineCount > 0) {
1006 const firstLine = document.lineAt(0).text;
1007 if (firstLine.startsWith("#!")) {
1008 insertLine = 1;
1009 }
1010 }
1011 return insertLine;
1012 }
1013
1023 private async writeHeaderToFile(document: vscode.TextDocument, comments: string[], languageId?: string): Promise<number> {
1024 logger.debug(getMessage("inFunction", "writeHeaderToFile", "CommentGenerator"));
1025
1026 const headerLines = await this.buildTheHeader(comments, languageId);
1027 const headerText = headerLines.join("");
1028 const edit = new vscode.WorkspaceEdit();
1029 const insertLine: number = this.skipFirstLineInDocument(document);
1030 edit.insert(
1031 document.uri,
1032 new vscode.Position(insertLine, 0),
1033 headerText
1034 );
1035
1036 await vscode.workspace.applyEdit(edit);
1037 return this.Config.get("statusSuccess");
1038 }
1039
1051 async injectHeader() {
1052 logger.debug(getMessage("inFunction", "injectHeader", "CommentGenerator"));
1053 const editor = vscode.window.activeTextEditor;
1054 if (editor === undefined) {
1055 logger.error(getMessage("noFocusedEditors"));
1056 logger.Gui.error(getMessage("openFileToApplyHeader"));
1057 return;
1058 }
1059 this.updateFileInfo(editor.document);
1060 // Checking that the meta data is filled out.
1061 if (
1062 this.documentBody === undefined || this.filePath === undefined
1063 || this.fileName === undefined || this.fileExtension === undefined
1064 || this.languageId === undefined || this.documentEOL === undefined
1065 || this.documentVersion === undefined
1066 ) {
1067 logger.error(getMessage("corruptedFileMetaData"));
1068 logger.Gui.error(getMessage("errorDuringFunctionCall", "injectHeader"));
1069 return;
1070 }
1071 // Making sure that the target document is still open.
1072 if (this.documentBody.isClosed) {
1073 logger.warning(getMessage("closedDocument"));
1074 logger.Gui.warning(getMessage("updateAbortedBecauseFileClosedSyncCancelled"));
1075 return;
1076 }
1077 // Some logging
1078 const msg = getMessage("inputArgs", JSON.stringify(this.documentBody), JSON.stringify(this.filePath), JSON.stringify(this.fileName), JSON.stringify(this.fileExtension), JSON.stringify(this.languageId), JSON.stringify(this.documentEOL), JSON.stringify(this.documentVersion));
1079 logger.Gui.debug(msg);
1080 logger.debug(msg);
1081 // Determining the correct comment prefix
1082 const determineComment: CommentStyle = await this.determineCorrectComment();
1083 const comments: string[] = await this.getCorrectCommentPrefix(determineComment);
1084 // attempt to locate the header
1085 let response: boolean | undefined = this.locateIfHeaderPresent(comments);
1086 if (response === undefined) {
1087 logger.Gui.warning(getMessage("updateAbortedBecauseFileClosedSyncCancelled"));
1088 return;
1089 }
1090 if (response === true) {
1091 logger.Gui.info(getMessage("updatingEditionDate"));
1092 await this.updateEditDate(editor.document, comments);
1093 return;
1094 }
1095 if (response === false) {
1096 let status: number = await this.writeHeaderToFile(editor.document, comments, determineComment.language);
1097 if (status === this.Config.get("statusError")) {
1098 logger.Gui.error(getMessage("headerWriteFailed"));
1099 return;
1100 }
1101 logger.Gui.info(getMessage("headerWriteSuccess"));
1102 }
1103 }
1104
1113 private async allowedToActivate(): Promise<boolean> {
1114 logger.debug(getMessage("inFunction", "allowedToActivate", "CommentGenerator"));
1115 const ignored: string[] = CodeConfig.get("extensionIgnore") ?? [];
1116
1117 for (const pattern of ignored) {
1118 if (
1119 this.fileExtension && minimatch(this.fileExtension, pattern) ||
1120 this.fileName && minimatch(this.fileName, pattern) ||
1121 this.filePath && minimatch(this.filePath, pattern)
1122 ) {
1123 return false;
1124 }
1125 }
1126
1127 return true;
1128 }
1129
1138 updateLogoInstanceRandomiser(randomLogoInstance: RandomLogo): void {
1139 logger.debug(getMessage("inFunction", "updateLogoInstanceRandomiser", "CommentGenerator"));
1140 this.randomLogo = randomLogoInstance;
1141 }
1142
1153 async refreshHeader(document: vscode.TextDocument | undefined) {
1154 logger.debug(getMessage("inFunction", "refreshHeader", "CommentGenerator"));
1155 const refreshOnSave: boolean = CodeConfig.get("refreshOnSave");
1156 const promptToCreateIfMissing: boolean = CodeConfig.get("promptToCreateIfMissing");
1157 if (!refreshOnSave) {
1158 return;
1159 }
1160 if (document === undefined) {
1161 logger.error(getMessage("noDocumentProvided"));
1162 return;
1163 }
1164 this.updateFileInfo(document);
1165 // Checking that the meta data is filled out.
1166 if (
1167 this.documentBody === undefined || this.filePath === undefined
1168 || this.fileName === undefined || this.fileExtension === undefined
1169 || this.languageId === undefined || this.documentEOL === undefined
1170 || this.documentVersion === undefined
1171 ) {
1172 logger.error(getMessage("corruptedFileMetaData"));
1173 logger.Gui.error(getMessage("errorDuringFunctionCall", "injectHeader"));
1174 return;
1175 }
1176 // Check that the file is not in the exclusion list.
1177 if (!await this.allowedToActivate()) {
1178 logger.info(getMessage("fileExcludedActivationDisabled"));
1179 return;
1180 }
1181 // Making sure that the target document is still open.
1182 if (this.documentBody.isClosed) {
1183 logger.warning(getMessage("closedDocument"));
1184 logger.Gui.warning(getMessage("updateAbortedBecauseFileClosedSyncCancelled"));
1185 return;
1186 }
1187 // Some logging
1188 const msg = getMessage("inputArgs", JSON.stringify(this.documentBody), JSON.stringify(this.filePath), JSON.stringify(this.fileName), JSON.stringify(this.fileExtension), JSON.stringify(this.languageId), JSON.stringify(this.documentEOL), JSON.stringify(this.documentVersion));
1189 logger.Gui.debug(msg);
1190 logger.debug(msg);
1191 // Determining the correct comment prefix
1192 const determineComment: CommentStyle = await this.determineCorrectComment();
1193 const comments: string[] = await this.getCorrectCommentPrefix(determineComment);
1194 // attempt to locate the header
1195 const response: boolean | undefined = this.locateIfHeaderPresent(comments);
1196 if (response === undefined) {
1197 logger.Gui.warning(getMessage("updateAbortedBecauseFileClosedSyncCancelled"));
1198 return;
1199 }
1200 if (response === false) {
1202 logger.Gui.info(getMessage("headerNotFound"));
1203 return;
1204 }
1205 logger.Gui.warning(getMessage("headerNotFound"));
1206 const questionResponse: boolean = await query.confirm(getMessage("headerInjectQuestion"));
1207 if (questionResponse === false) {
1208 logger.Gui.info(getMessage("headerInjectQuestionRefused"));
1209 return;
1210 }
1211 const status: number = await this.writeHeaderToFile(document, comments, determineComment.language);
1212 if (status === this.Config.get("statusError")) {
1213 logger.Gui.error(getMessage("headerWriteFailed"));
1214 return;
1215 }
1216 logger.Gui.info(getMessage("headerWriteSuccess"));
1217 }
1218 if (response === true) {
1219 logger.Gui.info(getMessage("updatingEditionDate"));
1220 await this.updateEditDate(document, comments);
1221 return;
1222 }
1223 }
1224}
Intelligent file header generation and management system.
constructor(languageComment:LazyFileLoader|undefined=undefined, editor:vscode.TextEditor|undefined=undefined, randomLogoInstance:RandomLogo|undefined=undefined)
Constructor for CommentGenerator class.
Generic lazy file loader with caching and type safety @template T The expected type of the loaded fil...
import *as vscode from vscode
export const languagePrepend
Array of the languages with the data to append.
Definition constants.ts:261
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAAv3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjabVBbEsMgCPznFD2CAho5jknTmd6gx qtNJMEqCKH4h lRj6dADxVZugptTqwzYer65UeIe5DWUctXFzIXEu5EdIHqrWYry UL6xZmlG7UnJa57b oHlEkAAAGEaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDUBSFT1OlKhWHFhFxyFA72UVFHGsVilAh1AqtOpi89A aNCQpLo6Ca8HBn8Wqg4uzrg6ugiD4A IuOCm6SIn3JYUWsT64vI z3jncdx8gNCpMs3rigKbbZjqZELO5VTHwin4MU4UQlZllzElSCl3X1z18fL L8azu9 Ma56LLAM8NmJj1PHCYWix2sdDArmRrxNHFE1XTKF7Ieq5y3OGuVGmv1yV8YzOsry1ynGkMSi1iCBBEKaiijAhsx2nVSLKTpPNHFP r6JXIp5CqDkWMBVWiQXT yerVWYmvSSggmg98VxPsaBwC7QrDvO97HjNE8A zNwpbf91QYw KqFQAN7P6JtyQOgWGFjz5tY6x kDkKFZpW6Ag0MgWqTs9S7v7uuc2793WvP7AZKlcrMQx gGAAANcmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDowOWQ3ODk3OS03YjNiLTRhMTgtODM5ZS1lMDgwOGNjMmUzY2EiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTM2YWE3YmMtN2QzZS00ZDJkLWIxMjItYTFhZjQwMjkzYjI5IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OTc2ZWEzNTgtNTNlNy00ODZkLWIzMzQtMjhmZWY1N2IyZWIzIgogICBHSU1QOkFQST0iMy4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE3NTg1MzI3OTM2NzA4NzIiCiAgIEdJTVA6VmVyc2lvbj0iMy4wLjQiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjU6MDk6MjJUMTE6MTk6NTArMDI6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI1OjA5OjIyVDExOjE5OjUwKzAyOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZGE1MDJhZWEtNDM0MS00NjdjLTgwMzEtYjUwMmU2OGFhYjkwIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHSU1QIDMuMC40IChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjUtMDktMjJUMTE6MTk6NTMrMDI6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8 QZaInQAAAAZiS0dEAAAAAAAA UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB kJFgkTNb1wNOYAABokSURBVHja7V15dFRF1r9V7 WW7mwsAZJ0SJpElARhUBM0gKNwjsM2gIMw oF Ss4MHy5DmBEB56g4Is6ZIQGRJYownzIalCUzLnj0Cx7GBZhAWISIMGaTYIBgku5Od7 t7vdH8pruTifpzkaAd8 pk8573fWqbv3q3lu3bt1HEPEkAAyAThLf8uNBna2AQhfJW4EkSV2rgOd5SEpKavWF yv QjEZjq58rigLJyclAqfdZZMaMGbX5 fmDAQAIItb2jbnQWVK70KUK8Kp2IWAuYOcrSEpKAkJIwG0GQ5OtXekCBUDabss6qIABEAaEEKitrXVnZ2eLwaSy3w uPI2CLCtAgAMAgLFjx oqKyt59b7a3VZMbJYDzXJBp NAUZoFSWVlJa sKCgoK6NLgSXBSdOnGhseQAiImRnZ0u T21TFiAqmJgYj3PmzHF4ryiK7PuNDipAHDhwICIirly58kJ1daUz8L4XylarFX744YdW45CcnNzcmSvyAMrLy vqXOiKPBgEV4koXGXqmw0YOnQoDB06NKQK9u3bdz6YWdPpBqhGRWjoZsBQBkIxQBD12hA0y1vVBiOEgCIrYVmLXWxAs7z2teE4noPt27fbw7Gyg89PijA02RpETalWZ7N42rJlCzDlSl8kSYKpU6fqAAAEQYCHHnzIuWv3Lsvx48drb7311sGt6vO1zhARGWNotVrRarUiYwzbJwWLiz rSUyMR0QFRVFEH6mNR44caXK73aLH45EREQsKCjy JTMzEyPeiclJQVGjhwZYTQadZRSTpIkGDx4sCAIgtguB1TV0pZ6aY8DiIhlZWVNKjMREQVBUH7 ziBhdaEVB8KtINzva8qo29cH3dEAvKGHQGtA322AIivQG hs1QDGGAwdOhQoR0OSclarFbKysuq7zyZk4dmEiAoQgu16tXoNA1fHKPUrV5kDhBCQJAkYY73VABZQAEpKShyKokB fr49JPM80ESSJRmtVqufW7A9kywhYQhmZd3xk2qSqYYtImJCQkKHNdC2etbsEWABrljFb UkCBLwvB4I4bzM3L17d OpU6caEBFmzZrlfuaZZ wqOIOBlA JiCQnJLkddu0tS7Ytm2brCgKL8uy99Y777xD33vvvUhCCJyvOS lpqUq fv MREBE3btzoREQ8ePCgK3Ct0U4DWEgLE98GFBYWlvvenTRpknP8 PGNKp6C1dnFBiAmJibi7bff lPg9dTUVCmwjtWrVzcsW7bM3o3rAn9yu91gMplAkRU4 e1pXpZl0Ol03vsVFRVcQUGBpV05QCgJw RmV1bIwKCkpMSh1sHxnPfhJ0 etCMiBD682yXhkiVLdOqqWd0tYYzBiBEjotrqTLfoggiTBQAoHD582Hju3Dk3YzJyHIGH uvXrltuucXruAjJKmaMQXJyMlRVVYVsDwRzdQc2dO3atbWzZs1q5R g21KrgQBqiziO83 U16fK Bgc7OFtrgsCvdo9uTjVFiZaA7QGXPX9ght BDQGaAzQGKAx4GpSyEuSr7 Kysru7xDodK ffvOP LII GEEBgyZEj9oUOHYvsUAhDR6zP0vdZ1BjQvWhjKgKgA5Tg PyMi6ZR5r8mAnpIBPcZ7NegSA pSuSFfxTtzTffbLbZbKb09HRp0aJF5mPHjkWkp6db3n777foZM2Y4rxIDWBil60j45JNP6jdv3txYVVVVDwCg1 th vz5sRcvXoTDhw b6 rq3L0kAxjwPA83DU8FURSDOmWuqAraLq8REbZt2ybzvA4o5QGZKvlbj8mAAQN0c fONZ49e9Yv5Pf2228X586d22 hfqX3ieB47j DYcgu3tuN1uZenSpdx export const languageAppend
Array of the languages with the data to prepend.
Definition constants.ts:258
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAAv3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjabVBbEsMgCPznFD2CAho5jknTmd6gx qtNJMEqCKH4h lRj6dADxVZugptTqwzYer65UeIe5DWUctXFzIXEu5EdIHqrWYry UL6xZmlG7UnJa57b oHlEkAAAGEaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDUBSFT1OlKhWHFhFxyFA72UVFHGsVilAh1AqtOpi89A aNCQpLo6Ca8HBn8Wqg4uzrg6ugiD4A IuOCm6SIn3JYUWsT64vI z3jncdx8gNCpMs3rigKbbZjqZELO5VTHwin4MU4UQlZllzElSCl3X1z18fL L8azu9 Ma56LLAM8NmJj1PHCYWix2sdDArmRrxNHFE1XTKF7Ieq5y3OGuVGmv1yV8YzOsry1ynGkMSi1iCBBEKaiijAhsx2nVSLKTpPNHFP r6JXIp5CqDkWMBVWiQXT yerVWYmvSSggmg98VxPsaBwC7QrDvO97HjNE8A zNwpbf91QYw KqFQAN7P6JtyQOgWGFjz5tY6x kDkKFZpW6Ag0MgWqTs9S7v7uuc2793WvP7AZKlcrMQx gGAAANcmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDowOWQ3ODk3OS03YjNiLTRhMTgtODM5ZS1lMDgwOGNjMmUzY2EiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTM2YWE3YmMtN2QzZS00ZDJkLWIxMjItYTFhZjQwMjkzYjI5IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OTc2ZWEzNTgtNTNlNy00ODZkLWIzMzQtMjhmZWY1N2IyZWIzIgogICBHSU1QOkFQST0iMy4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE3NTg1MzI3OTM2NzA4NzIiCiAgIEdJTVA6VmVyc2lvbj0iMy4wLjQiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjU6MDk6MjJUMTE6MTk6NTArMDI6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI1OjA5OjIyVDExOjE5OjUwKzAyOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZGE1MDJhZWEtNDM0MS00NjdjLTgwMzEtYjUwMmU2OGFhYjkwIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHSU1QIDMuMC40IChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjUtMDktMjJUMTE6MTk6NTMrMDI6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8 QZaInQAAAAZiS0dEAAAAAAAA UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB kJFgkTNb1wNOYAABokSURBVHja7V15dFRF1r9V7 WW7mwsAZJ0SJpElARhUBM0gKNwjsM2gIMw oF Ss4MHy5DmBEB56g4Is6ZIQGRJYownzIalCUzLnj0Cx7GBZhAWISIMGaTYIBgku5Od7 t7vdH8pruTifpzkaAd8 pk8573fWqbv3q3lu3bt1HEPEkAAyAThLf8uNBna2AQhfJW4EkSV2rgOd5SEpKavWF yv QjEZjq58rigLJyclAqfdZZMaMGbX5 fmDAQAIItb2jbnQWVK70KUK8Kp2IWAuYOcrSEpKAkJIwG0GQ5OtXekCBUDabss6qIABEAaEEKitrXVnZ2eLwaSy3w uPI2CLCtAgAMAgLFjx oqKyt59b7a3VZMbJYDzXJBp NAUZoFSWVlJa sKCgoK6NLgSXBSdOnGhseQAiImRnZ0u T21TFiAqmJgYj3PmzHF4ryiK7PuNDipAHDhwICIirly58kJ1daUz8L4XylarFX744YdW45CcnNzcmSvyAMrLy vqXOiKPBgEV4koXGXqmw0YOnQoDB06NKQK9u3bdz6YWdPpBqhGRWjoZsBQBkIxQBD12hA0y1vVBiOEgCIrYVmLXWxAs7z2teE4noPt27fbw7Gyg89PijA02RpETalWZ7N42rJlCzDlSl8kSYKpU6fqAAAEQYCHHnzIuWv3Lsvx48drb7311sGt6vO1zhARGWNotVrRarUiYwzbJwWLiz rSUyMR0QFRVFEH6mNR44caXK73aLH45EREQsKCjy JTMzEyPeiclJQVGjhwZYTQadZRSTpIkGDx4sCAIgtguB1TV0pZ6aY8DiIhlZWVNKjMREQVBUH7 ziBhdaEVB8KtINzva8qo29cH3dEAvKGHQGtA322AIivQG hs1QDGGAwdOhQoR0OSclarFbKysuq7zyZk4dmEiAoQgu16tXoNA1fHKPUrV5kDhBCQJAkYY73VABZQAEpKShyKokB fr49JPM80ESSJRmtVqufW7A9kywhYQhmZd3xk2qSqYYtImJCQkKHNdC2etbsEWABrljFb UkCBLwvB4I4bzM3L17d OpU6caEBFmzZrlfuaZZ wqOIOBlA JiCQnJLkddu0tS7Ytm2brCgKL8uy99Y777xD33vvvUhCCJyvOS lpqUq fv MREBE3btzoREQ8ePCgK3Ct0U4DWEgLE98GFBYWlvvenTRpknP8 PGNKp6C1dnFBiAmJibi7bff lPg9dTUVCmwjtWrVzcsW7bM3o3rAn9yu91gMplAkRU4 e1pXpZl0Ol03vsVFRVcQUGBpV05QCgJw RmV1bIwKCkpMSh1sHxnPfhJ0 etCMiBD682yXhkiVLdOqqWd0tYYzBiBEjotrqTLfoggiTBQAoHD582Hju3Dk3YzJyHIGH uvXrltuucXruAjJKmaMQXJyMlRVVYVsDwRzdQc2dO3atbWzZs1q5R g21KrgQBqiziO83 U16fK Bgc7OFtrgsCvdo9uTjVFiZaA7QGXPX9ght BDQGaAzQGKAx4GpSyEuSr7 Kysru7xDodK ffvOP LII GEEBgyZEj9oUOHYvsUAhDR6zP0vdZ1BjQvWhjKgKgA5Tg PyMi6ZR5r8mAnpIBPcZ7NegSA pSuSFfxTtzTffbLbZbKb09HRp0aJF5mPHjkWkp6db3n777foZM2Y4rxIDWBil60j45JNP6jdv3txYVVVVDwCg1 th vz5sRcvXoTDhw b6 rq3L0kAxjwPA83DU8FURSDOmWuqAraLq8REbZt2ybzvA4o5QGZKvlbj8mAAQN0c fONZ49e9Yv5Pf2228X586d22 hfqX3ieB47j DYcgu3tuN1uZenSpdx export const string
Definition constants.ts:258
export const preferSingleLineComments
Prefer single line comments when possible.
Definition constants.ts:278
export const promptToCreateIfMissing
Whether to prompt user to create header if missing during operations.
Definition constants.ts:232
export const randomLogo
Whether to use random logo selection instead of default logo.
Definition constants.ts:235
export const refreshOnSave
Whether to automatically refresh headers when files are saved.
Definition constants.ts:229
Defines comment style configuration for different programming languages.
Structure representing a loaded ASCII art logo with metadata.
export const logger
Singleton logger instance providing unified logging interface for the entire extension.
Definition logger.ts:910
const instance
Singleton logger instance for application-wide use.
Definition logger.ts:870
export const getMessage
Exported function for direct message retrieval.
export type CodeConfigType
Type alias for the Configuration class.
export const CodeConfig
Exported configuration singleton for extension-wide access @export Primary configuration interface us...
export const query
Convenience singleton export for direct access to Query functionality @export Primary interface for u...
Definition querier.ts:345