@@ -96,8 +96,8 @@ export class FileManager {
9696
9797 const repoCleaned = repoName . replace ( / \/ / g, "-" ) ;
9898 const ownerCleaned = owner . replace ( / \/ / g, "-" ) ;
99- const issueFolder = ` ${ repo . issueFolder } / ${ ownerCleaned } / ${ repoCleaned } ` ;
100- const pullRequestFolder = ` ${ repo . pullRequestFolder } / ${ ownerCleaned } / ${ repoCleaned } ` ;
99+ const issueFolder = this . getIssueFolderPath ( repo , ownerCleaned , repoCleaned ) ;
100+ const pullRequestFolder = this . getPullRequestFolderPath ( repo , ownerCleaned , repoCleaned ) ;
101101
102102 await this . cleanupEmptyIssueFolder (
103103 repo ,
@@ -117,24 +117,41 @@ export class FileManager {
117117
118118 // ----- Private helper methods -----
119119
120+ /**
121+ * Get the issue folder path for a repository
122+ */
123+ private getIssueFolderPath ( repo : RepositoryTracking , ownerCleaned : string , repoCleaned : string ) : string {
124+ if ( repo . useCustomIssueFolder && repo . customIssueFolder && repo . customIssueFolder . trim ( ) ) {
125+ return repo . customIssueFolder . trim ( ) ;
126+ }
127+ return `${ repo . issueFolder } /${ ownerCleaned } /${ repoCleaned } ` ;
128+ }
129+
130+ /**
131+ * Get the pull request folder path for a repository
132+ */
133+ private getPullRequestFolderPath ( repo : RepositoryTracking , ownerCleaned : string , repoCleaned : string ) : string {
134+ if ( repo . useCustomPullRequestFolder && repo . customPullRequestFolder && repo . customPullRequestFolder . trim ( ) ) {
135+ return repo . customPullRequestFolder . trim ( ) ;
136+ }
137+ return `${ repo . pullRequestFolder } /${ ownerCleaned } /${ repoCleaned } ` ;
138+ }
139+
120140 private async cleanupDeletedIssues (
121141 repo : RepositoryTracking ,
122142 ownerCleaned : string ,
123143 repoCleaned : string ,
124144 allIssuesIncludingRecentlyClosed : any [ ] ,
125145 ) : Promise < void > {
126- const repoFolder = this . app . vault . getAbstractFileByPath (
127- `${ repo . issueFolder } /${ ownerCleaned } /${ repoCleaned } ` ,
128- ) ;
146+ const issueFolderPath = this . getIssueFolderPath ( repo , ownerCleaned , repoCleaned ) ;
147+ const repoFolder = this . app . vault . getAbstractFileByPath ( issueFolderPath ) ;
129148
130149 if ( repoFolder ) {
131150 const files = this . app . vault
132151 . getFiles ( )
133152 . filter (
134153 ( file ) =>
135- file . path . startsWith (
136- `${ repo . issueFolder } /${ ownerCleaned } /${ repoCleaned } /` ,
137- ) && file . extension === "md" ,
154+ file . path . startsWith ( `${ issueFolderPath } /` ) && file . extension === "md" ,
138155 ) ;
139156
140157 for ( const file of files ) {
@@ -184,18 +201,15 @@ export class FileManager {
184201 repoCleaned : string ,
185202 allPullRequestsIncludingRecentlyClosed : any [ ] ,
186203 ) : Promise < void > {
187- const repoFolder = this . app . vault . getAbstractFileByPath (
188- `${ repo . pullRequestFolder } /${ ownerCleaned } /${ repoCleaned } ` ,
189- ) ;
204+ const pullRequestFolderPath = this . getPullRequestFolderPath ( repo , ownerCleaned , repoCleaned ) ;
205+ const repoFolder = this . app . vault . getAbstractFileByPath ( pullRequestFolderPath ) ;
190206
191207 if ( repoFolder ) {
192208 const files = this . app . vault
193209 . getFiles ( )
194210 . filter (
195211 ( file ) =>
196- file . path . startsWith (
197- `${ repo . pullRequestFolder } /${ ownerCleaned } /${ repoCleaned } /` ,
198- ) && file . extension === "md" ,
212+ file . path . startsWith ( `${ pullRequestFolderPath } /` ) && file . extension === "md" ,
199213 ) ;
200214
201215 for ( const file of files ) {
@@ -244,15 +258,20 @@ export class FileManager {
244258 issue : any ,
245259 ) : Promise < void > {
246260 const fileName = `Issue - ${ issue . number } .md` ;
247- await this . ensureFolderExists ( repo . issueFolder ) ;
248- await this . ensureFolderExists ( `${ repo . issueFolder } /${ ownerCleaned } ` ) ;
249- await this . ensureFolderExists (
250- `${ repo . issueFolder } /${ ownerCleaned } /${ repoCleaned } ` ,
251- ) ;
261+ const issueFolderPath = this . getIssueFolderPath ( repo , ownerCleaned , repoCleaned ) ;
252262
253- const file = this . app . vault . getAbstractFileByPath (
254- `${ repo . issueFolder } /${ ownerCleaned } /${ repoCleaned } /${ fileName } ` ,
255- ) ;
263+ // Ensure folder structure exists
264+ if ( repo . useCustomIssueFolder && repo . customIssueFolder && repo . customIssueFolder . trim ( ) ) {
265+ // For custom folders, just ensure the custom path exists
266+ await this . ensureFolderExists ( repo . customIssueFolder . trim ( ) ) ;
267+ } else {
268+ // For default structure, ensure nested path exists
269+ await this . ensureFolderExists ( repo . issueFolder ) ;
270+ await this . ensureFolderExists ( `${ repo . issueFolder } /${ ownerCleaned } ` ) ;
271+ await this . ensureFolderExists ( `${ repo . issueFolder } /${ ownerCleaned } /${ repoCleaned } ` ) ;
272+ }
273+
274+ const file = this . app . vault . getAbstractFileByPath ( `${ issueFolderPath } /${ fileName } ` ) ;
256275
257276 const [ owner , repoName ] = repo . repository . split ( "/" ) ;
258277 const comments = await this . gitHubClient . fetchIssueComments (
@@ -319,10 +338,7 @@ export class FileManager {
319338 }
320339 }
321340 } else {
322- await this . app . vault . create (
323- `${ repo . issueFolder } /${ ownerCleaned } /${ repoCleaned } /${ fileName } ` ,
324- content ,
325- ) ;
341+ await this . app . vault . create ( `${ issueFolderPath } /${ fileName } ` , content ) ;
326342 this . noticeManager . debug ( `Created issue file for ${ issue . number } ` ) ;
327343 }
328344 }
@@ -334,18 +350,20 @@ export class FileManager {
334350 pr : any ,
335351 ) : Promise < void > {
336352 const fileName = `Pull Request - ${ pr . number } .md` ;
353+ const pullRequestFolderPath = this . getPullRequestFolderPath ( repo , ownerCleaned , repoCleaned ) ;
337354
338- await this . ensureFolderExists ( repo . pullRequestFolder ) ;
339- await this . ensureFolderExists (
340- `${ repo . pullRequestFolder } /${ ownerCleaned } ` ,
341- ) ;
342- await this . ensureFolderExists (
343- `${ repo . pullRequestFolder } /${ ownerCleaned } /${ repoCleaned } ` ,
344- ) ;
355+ // Ensure folder structure exists
356+ if ( repo . useCustomPullRequestFolder && repo . customPullRequestFolder && repo . customPullRequestFolder . trim ( ) ) {
357+ // For custom folders, just ensure the custom path exists
358+ await this . ensureFolderExists ( repo . customPullRequestFolder . trim ( ) ) ;
359+ } else {
360+ // For default structure, ensure nested path exists
361+ await this . ensureFolderExists ( repo . pullRequestFolder ) ;
362+ await this . ensureFolderExists ( `${ repo . pullRequestFolder } /${ ownerCleaned } ` ) ;
363+ await this . ensureFolderExists ( `${ repo . pullRequestFolder } /${ ownerCleaned } /${ repoCleaned } ` ) ;
364+ }
345365
346- const file = this . app . vault . getAbstractFileByPath (
347- `${ repo . pullRequestFolder } /${ ownerCleaned } /${ repoCleaned } /${ fileName } ` ,
348- ) ;
366+ const file = this . app . vault . getAbstractFileByPath ( `${ pullRequestFolderPath } /${ fileName } ` ) ;
349367
350368 const [ owner , repoName ] = repo . repository . split ( "/" ) ;
351369 const comments = await this . gitHubClient . fetchPullRequestComments (
@@ -412,10 +430,7 @@ export class FileManager {
412430 }
413431 }
414432 } else {
415- await this . app . vault . create (
416- `${ repo . pullRequestFolder } /${ ownerCleaned } /${ repoCleaned } /${ fileName } ` ,
417- content ,
418- ) ;
433+ await this . app . vault . create ( `${ pullRequestFolderPath } /${ fileName } ` , content ) ;
419434 this . noticeManager . debug ( `Created PR file for ${ pr . number } ` ) ;
420435 }
421436 }
@@ -546,28 +561,31 @@ ${this.formatComments(comments, this.settings.escapeMode)}
546561 }
547562 }
548563
549- if ( files . length === 0 ) {
550- this . noticeManager . info (
551- `Deleting empty folder: ${ issueFolder } ` ,
552- ) ;
553- const folder =
554- this . app . vault . getAbstractFileByPath ( issueFolder ) ;
555- if ( folder instanceof TFolder && folder . children . length === 0 ) {
556- await this . app . fileManager . trashFile ( folder ) ;
557- }
558- }
559-
560- const issueOwnerFolder = this . app . vault . getAbstractFileByPath (
561- `${ repo . issueFolder } /${ ownerCleaned } ` ,
562- ) ;
563-
564- if ( issueOwnerFolder instanceof TFolder ) {
565- const files = issueOwnerFolder . children ;
564+ // Only cleanup nested folder structure if not using custom folder
565+ if ( ! repo . useCustomIssueFolder || ! repo . customIssueFolder || ! repo . customIssueFolder . trim ( ) ) {
566566 if ( files . length === 0 ) {
567567 this . noticeManager . info (
568- `Deleting empty folder: ${ issueOwnerFolder . path } ` ,
568+ `Deleting empty folder: ${ issueFolder } ` ,
569569 ) ;
570- await this . app . fileManager . trashFile ( issueOwnerFolder ) ;
570+ const folder =
571+ this . app . vault . getAbstractFileByPath ( issueFolder ) ;
572+ if ( folder instanceof TFolder && folder . children . length === 0 ) {
573+ await this . app . fileManager . trashFile ( folder ) ;
574+ }
575+ }
576+
577+ const issueOwnerFolder = this . app . vault . getAbstractFileByPath (
578+ `${ repo . issueFolder } /${ ownerCleaned } ` ,
579+ ) ;
580+
581+ if ( issueOwnerFolder instanceof TFolder ) {
582+ const files = issueOwnerFolder . children ;
583+ if ( files . length === 0 ) {
584+ this . noticeManager . info (
585+ `Deleting empty folder: ${ issueOwnerFolder . path } ` ,
586+ ) ;
587+ await this . app . fileManager . trashFile ( issueOwnerFolder ) ;
588+ }
571589 }
572590 }
573591 }
@@ -606,38 +624,40 @@ ${this.formatComments(comments, this.settings.escapeMode)}
606624 }
607625 }
608626
609- if ( files . length === 0 ) {
610- this . noticeManager . info (
611- `Deleting empty folder: ${ pullRequestFolder } ` ,
612- ) ;
613- const folder =
614- this . app . vault . getAbstractFileByPath ( pullRequestFolder ) ;
615- if ( folder instanceof TFolder && folder . children . length === 0 ) {
616- await this . app . fileManager . trashFile ( folder ) ;
617- }
618- }
619-
620- const pullRequestOwnerFolder = this . app . vault . getAbstractFileByPath (
621- `${ repo . pullRequestFolder } /${ ownerCleaned } ` ,
622- ) ;
623-
624- if ( pullRequestOwnerFolder instanceof TFolder ) {
625- const files = pullRequestOwnerFolder . children ;
627+ // Only cleanup nested folder structure if not using custom folder
628+ if ( ! repo . useCustomPullRequestFolder || ! repo . customPullRequestFolder || ! repo . customPullRequestFolder . trim ( ) ) {
626629 if ( files . length === 0 ) {
627630 this . noticeManager . info (
628- `Deleting empty folder: ${ pullRequestOwnerFolder . path } ` ,
629- ) ;
630- await this . app . fileManager . trashFile (
631- pullRequestOwnerFolder ,
631+ `Deleting empty folder: ${ pullRequestFolder } ` ,
632632 ) ;
633+ const folder =
634+ this . app . vault . getAbstractFileByPath ( pullRequestFolder ) ;
635+ if ( folder instanceof TFolder && folder . children . length === 0 ) {
636+ await this . app . fileManager . trashFile ( folder ) ;
637+ }
638+ }
639+
640+ const pullRequestOwnerFolder = this . app . vault . getAbstractFileByPath (
641+ `${ repo . pullRequestFolder } /${ ownerCleaned } ` ,
642+ ) ;
643+
644+ if ( pullRequestOwnerFolder instanceof TFolder ) {
645+ const files = pullRequestOwnerFolder . children ;
646+ if ( files . length === 0 ) {
647+ this . noticeManager . info (
648+ `Deleting empty folder: ${ pullRequestOwnerFolder . path } ` ,
649+ ) ;
650+ await this . app . fileManager . trashFile (
651+ pullRequestOwnerFolder ,
652+ ) ;
653+ }
633654 }
634655 }
635656 }
636657 }
637658
638- /**
639- * Format comments section for issues and pull requests
640- */
659+ // Format comments section for issues and pull requests
660+
641661 private formatComments (
642662 comments : any [ ] ,
643663 escapeMode : "disabled" | "normal" | "strict" | "veryStrict" ,
@@ -647,9 +667,7 @@ ${this.formatComments(comments, this.settings.escapeMode)}
647667 }
648668
649669 comments . sort (
650- ( a , b ) =>
651- new Date ( a . created_at ) . getTime ( ) -
652- new Date ( b . created_at ) . getTime ( ) ,
670+ ( a , b ) => new Date ( a . created_at ) . getTime ( ) - new Date ( b . created_at ) . getTime ( ) ,
653671 ) ;
654672
655673 let commentSection = "\n## Comments\n\n" ;
0 commit comments