22 * @file commentGenerator.ts
33 * @brief Comprehensive comment and header generation system for AsperHeader extension
44 * @author Henry Letellier
5- * @version 1.0.14
5+ * @version 1.0.18
66 * @since 1.0.0
77 * @date 2025
88 *
@@ -167,6 +167,8 @@ export class CommentGenerator {
167167 private projectCopyRight : string = this . Config . get ( "projectCopyright" ) ;
168168 /** @brief Whether to add blank line after multiline sections */
169169 private addBlankLineAfterMultiline : boolean = this . Config . get ( "headerAddBlankLineAfterMultiline" ) ;
170+ /** @brief Wether to remove trailing spaces after a generated line */
171+ private trimTrailingSpaces : boolean = this . Config . get ( "removeTrailingHeaderSpaces" ) ;
170172
171173 /**
172174 * @brief Constructor for CommentGenerator class
@@ -464,6 +466,13 @@ export class CommentGenerator {
464466 return final ;
465467 }
466468
469+ private mySmartTrimmer ( content : string ) : string {
470+ if ( this . trimTrailingSpaces ) {
471+ return content . trimEnd ( )
472+ }
473+ return content
474+ }
475+
467476 /**
468477 * @brief Formats a multi-line key-value section for the header
469478 * @param comment Comment prefix for each line
@@ -479,7 +488,8 @@ export class CommentGenerator {
479488 private addMultilineKey ( comment : string , eol : vscode . EndOfLine , tagName : string , tagDefinition : string [ ] ) : string {
480489 logger . debug ( getMessage ( "inFunction" , "addMultilineKey" , "CommentGenerator" ) ) ;
481490 const eolStr : string = this . determineNewLine ( eol ) ;
482- let final : string = comment + tagName + this . addKeyDefinitionSeparator ( ) + eolStr ;
491+ const keyLine : string = comment + tagName + this . mySmartTrimmer ( this . addKeyDefinitionSeparator ( ) ) + eolStr ;
492+ let final : string = keyLine ;
483493 for ( let i = 0 ; i < tagDefinition . length ; i ++ ) {
484494 final += comment + tagDefinition [ i ] + eolStr ;
485495 }
@@ -574,6 +584,101 @@ export class CommentGenerator {
574584 this . documentVersion = this . documentBody . version ;
575585 }
576586
587+ private prependIfPresent ( buildHeader : string [ ] ) : string [ ] {
588+
589+ // Apply language-specific prepend if configured
590+ const languageId = this . languageId ?. toLowerCase ( ) || "" ;
591+ const prependConfig = this . Config . get ( "languagePrepend" ) ;
592+ if ( prependConfig && prependConfig [ languageId ] ) {
593+ buildHeader . push ( prependConfig [ languageId ] ) ;
594+ logger . debug ( getMessage ( "languagePrependApplied" , languageId ) ) ;
595+ }
596+ return buildHeader ;
597+ }
598+
599+ private appendIfPresent ( buildHeader : string [ ] ) : string [ ] {
600+ // Apply language-specific append if configured
601+ const appendConfig = this . Config . get ( "languageAppend" ) ;
602+ if ( appendConfig && appendConfig [ languageId ] ) {
603+ buildHeader . push ( appendConfig [ languageId ] ) ;
604+ logger . debug ( getMessage ( "languageAppendApplied" , languageId ) ) ;
605+ }
606+
607+ // Remove trailing spaces if configured
608+ if ( this . Config . get ( "removeTrailingHeaderSpaces" ) ) {
609+ buildHeader = buildHeader . map ( line => line . trimEnd ( ) ) ;
610+ logger . debug ( getMessage ( "trailingSpacesRemoved" ) ) ;
611+ }
612+ return buildHeader ;
613+ }
614+
615+ private async getOverrideIfPresent ( determinedComment : CommentStyle ) : Promise < CommentStyle > {
616+ logger . debug ( getMessage ( "inFunction" , "getCorrectPrefix" , "CommentGenerator" ) ) ;
617+ let commentOpener : string = "" ;
618+ let commentMiddle : string = "" ;
619+ let commentCloser : string = "" ;
620+
621+ // Apply language-specific comment overrides if configured
622+ const languageId = this . languageId ?. toLowerCase ( ) || "" ;
623+ const singleLineOverride = this . Config . get ( "languageSingleLineComment" ) ;
624+ const multiLineOverride = this . Config . get ( "languageMultiLineComment" ) ;
625+
626+ let effectiveComment = { ...determinedComment } ;
627+
628+ if ( singleLineOverride && singleLineOverride [ languageId ] ) {
629+ effectiveComment . singleLine = Array . isArray ( singleLineOverride [ languageId ] )
630+ ? singleLineOverride [ languageId ]
631+ : [ singleLineOverride [ languageId ] ] ;
632+ logger . debug ( getMessage ( "singleLineCommentOverrideApplied" , languageId ) ) ;
633+ }
634+
635+ if ( multiLineOverride && multiLineOverride [ languageId ] ) {
636+ effectiveComment . multiLine = Array . isArray ( multiLineOverride [ languageId ] )
637+ ? multiLineOverride [ languageId ]
638+ : [ multiLineOverride [ languageId ] ] ;
639+ logger . debug ( getMessage ( "multiLineCommentOverrideApplied" , languageId ) ) ;
640+ }
641+
642+ // Determine comment style preference
643+ const preferSingleLine = this . Config . get ( "preferSingleLineComments" ) ;
644+ const hasMultiLine = effectiveComment . multiLine . length >= 2 ;
645+ const hasSingleLine = effectiveComment . singleLine . length > 0 ;
646+
647+ if ( hasMultiLine && ( ! preferSingleLine || ! hasSingleLine ) ) {
648+ // Use multi-line comments
649+ commentOpener = effectiveComment . multiLine [ 0 ] ;
650+ if ( effectiveComment . multiLine . length >= 3 ) {
651+ commentMiddle = effectiveComment . multiLine [ 1 ] ;
652+ commentCloser = effectiveComment . multiLine [ 2 ] ;
653+ } else {
654+ commentMiddle = "" ;
655+ commentCloser = effectiveComment . multiLine [ 1 ] ;
656+ }
657+ } else if ( hasSingleLine ) {
658+ // Use single-line comments
659+ if ( effectiveComment . prompt_comment_opening_type ) {
660+ // Ask the user for the type to use based on the single comments that are present.
661+ const commentString : string = await this . getSingleCommentOption ( effectiveComment . singleLine ) ;
662+ commentOpener = commentString ;
663+ commentMiddle = commentString ;
664+ commentCloser = commentString ;
665+ } else {
666+ commentOpener = effectiveComment . singleLine [ 0 ] ;
667+ commentMiddle = effectiveComment . singleLine [ 0 ] ;
668+ commentCloser = effectiveComment . singleLine [ 0 ] ;
669+ }
670+ } else {
671+ commentOpener = "" ;
672+ commentMiddle = "" ;
673+ commentCloser = "" ;
674+ }
675+
676+ commentOpener += this . Config . get ( "headerCommentSpacing" ) ;
677+ commentMiddle += this . Config . get ( "headerCommentSpacing" ) ;
678+ commentCloser += this . Config . get ( "headerCommentSpacing" ) ;
679+ return [ commentOpener , commentMiddle , commentCloser ] ;
680+ }
681+
577682 /**
578683 * @brief Determines comment prefixes based on comment style configuration
579684 * @param determinedComment Comment style configuration for the language
@@ -643,6 +748,8 @@ export class CommentGenerator {
643748 const commentMiddle : string = comments [ 1 ] || "" ;
644749 const commentCloser : string = comments [ 2 ] || "" ;
645750 let buildHeader : string [ ] = [ ] ;
751+ // Check wether there are elements required to be added before the header
752+ buildHeader = this . prependIfPresent ( buildHeader ) ;
646753 // Preparing the header content so that it can be put in a comment and written.
647754 if ( commentOpener . length > 0 ) {
648755 buildHeader . push ( `${ commentOpener } ${ this . determineNewLine ( eol ) } ` ) ;
@@ -687,6 +794,9 @@ export class CommentGenerator {
687794 if ( commentCloser . length > 0 ) {
688795 buildHeader . push ( `${ commentCloser } ${ this . determineNewLine ( eol ) } ` ) ;
689796 }
797+
798+ buildHeader = this . appendIfPresent ( buildHeader ) ;
799+
690800 return buildHeader ;
691801 }
692802
0 commit comments