@@ -81,7 +81,8 @@ type DiffLine struct {
8181
8282// DiffLineSectionInfo represents diff line section meta data
8383type DiffLineSectionInfo struct {
84- Path string
84+ Path string
85+ language * diffVarMutable [string ] // it will be filled later, so it must be a pointer to the DiffFile.language
8586
8687 // These line "idx" are 1-based line numbers
8788 // Left/Right refer to the left/right side of the diff:
@@ -165,15 +166,19 @@ func (d *DiffLine) GetLineTypeMarker() string {
165166}
166167
167168func (d * DiffLine ) getBlobExcerptQuery () string {
169+ language := ""
170+ if d .SectionInfo .language != nil {
171+ language = d .SectionInfo .language .value
172+ }
168173 query := fmt .Sprintf (
169174 "last_left=%d&last_right=%d&" +
170175 "left=%d&right=%d&" +
171176 "left_hunk_size=%d&right_hunk_size=%d&" +
172- "path=%s" ,
177+ "path=%s&filelang=%s " ,
173178 d .SectionInfo .LastLeftIdx , d .SectionInfo .LastRightIdx ,
174179 d .SectionInfo .LeftIdx , d .SectionInfo .RightIdx ,
175180 d .SectionInfo .LeftHunkSize , d .SectionInfo .RightHunkSize ,
176- url .QueryEscape (d .SectionInfo .Path ))
181+ url .QueryEscape (d .SectionInfo .Path ), url . QueryEscape ( language ) )
177182 return query
178183}
179184
@@ -266,11 +271,12 @@ func FillHiddenCommentIDsForDiffLine(line *DiffLine, lineComments map[int64][]*i
266271 line .SectionInfo .HiddenCommentIDs = hiddenCommentIDs
267272}
268273
269- func getDiffLineSectionInfo ( treePath , line string , lastLeftIdx , lastRightIdx int ) * DiffLineSectionInfo {
274+ func newDiffLineSectionInfo ( curFile * DiffFile , line string , lastLeftIdx , lastRightIdx int ) * DiffLineSectionInfo {
270275 leftLine , leftHunk , rightLine , rightHunk := git .ParseDiffHunkString (line )
271276
272277 return & DiffLineSectionInfo {
273- Path : treePath ,
278+ Path : curFile .Name ,
279+ language : & curFile .language ,
274280 LastLeftIdx : lastLeftIdx ,
275281 LastRightIdx : lastRightIdx ,
276282 LeftIdx : leftLine ,
@@ -290,7 +296,10 @@ func getLineContent(content string, locale translation.Locale) DiffInline {
290296
291297// DiffSection represents a section of a DiffFile.
292298type DiffSection struct {
293- file * DiffFile
299+ language * diffVarMutable [string ]
300+ highlightedLeftLines * diffVarMutable [map [int ]template.HTML ]
301+ highlightedRightLines * diffVarMutable [map [int ]template.HTML ]
302+
294303 FileName string
295304 Lines []* DiffLine
296305}
@@ -339,9 +348,9 @@ func (diffSection *DiffSection) getDiffLineForRender(diffLineType DiffLineType,
339348 var fileLanguage string
340349 var highlightedLeftLines , highlightedRightLines map [int ]template.HTML
341350 // when a "diff section" is manually prepared by ExcerptBlob, it doesn't have "file" information
342- if diffSection .file != nil {
343- fileLanguage = diffSection .file . Language
344- highlightedLeftLines , highlightedRightLines = diffSection .file . highlightedLeftLines , diffSection .file . highlightedRightLines
351+ if diffSection .language != nil {
352+ fileLanguage = diffSection .language . value
353+ highlightedLeftLines , highlightedRightLines = diffSection .highlightedLeftLines . value , diffSection .highlightedRightLines . value
345354 }
346355
347356 var lineHTML template.HTML
@@ -392,6 +401,11 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine, loc
392401 }
393402}
394403
404+ // diffVarMutable is a wrapper to make a variable mutable to be shared across structs
405+ type diffVarMutable [T any ] struct {
406+ value T
407+ }
408+
395409// DiffFile represents a file diff.
396410type DiffFile struct {
397411 // only used internally to parse Ambiguous filenames
@@ -418,7 +432,6 @@ type DiffFile struct {
418432 IsIncompleteLineTooLong bool
419433
420434 // will be filled by the extra loop in GitDiffForRender
421- Language string
422435 IsGenerated bool
423436 IsVendored bool
424437 SubmoduleDiffInfo * SubmoduleDiffInfo // IsSubmodule==true, then there must be a SubmoduleDiffInfo
@@ -430,9 +443,10 @@ type DiffFile struct {
430443 IsViewed bool // User specific
431444 HasChangedSinceLastReview bool // User specific
432445
433- // for render purpose only, will be filled by the extra loop in GitDiffForRender
434- highlightedLeftLines map [int ]template.HTML
435- highlightedRightLines map [int ]template.HTML
446+ // for render purpose only, will be filled by the extra loop in GitDiffForRender, they are 0-based
447+ language diffVarMutable [string ]
448+ highlightedLeftLines diffVarMutable [map [int ]template.HTML ]
449+ highlightedRightLines diffVarMutable [map [int ]template.HTML ]
436450}
437451
438452// GetType returns type of diff file.
@@ -470,6 +484,7 @@ func (diffFile *DiffFile) GetTailSectionAndLimitedContent(leftCommit, rightCommi
470484 Content : " " ,
471485 SectionInfo : & DiffLineSectionInfo {
472486 Path : diffFile .Name ,
487+ language : & diffFile .language ,
473488 LastLeftIdx : lastLine .LeftIdx ,
474489 LastRightIdx : lastLine .RightIdx ,
475490 LeftIdx : leftLineCount ,
@@ -907,6 +922,14 @@ func skipToNextDiffHead(input *bufio.Reader) (line string, err error) {
907922 return line , err
908923}
909924
925+ func newDiffSectionForDiffFile (curFile * DiffFile ) * DiffSection {
926+ return & DiffSection {
927+ language : & curFile .language ,
928+ highlightedLeftLines : & curFile .highlightedLeftLines ,
929+ highlightedRightLines : & curFile .highlightedRightLines ,
930+ }
931+ }
932+
910933func parseHunks (ctx context.Context , curFile * DiffFile , maxLines , maxLineCharacters int , input * bufio.Reader ) (lineBytes []byte , isFragment bool , err error ) {
911934 sb := strings.Builder {}
912935
@@ -964,12 +987,12 @@ func parseHunks(ctx context.Context, curFile *DiffFile, maxLines, maxLineCharact
964987 line := sb .String ()
965988
966989 // Create a new section to represent this hunk
967- curSection = & DiffSection { file : curFile }
990+ curSection = newDiffSectionForDiffFile ( curFile )
968991 lastLeftIdx = - 1
969992 curFile .Sections = append (curFile .Sections , curSection )
970993
971994 // FIXME: the "-1" can't be right, these "line idx" are all 1-based, maybe there are other bugs that covers this bug.
972- lineSectionInfo := getDiffLineSectionInfo (curFile . Name , line , leftLine - 1 , rightLine - 1 )
995+ lineSectionInfo := newDiffLineSectionInfo (curFile , line , leftLine - 1 , rightLine - 1 )
973996 diffLine := & DiffLine {
974997 Type : DiffLineSection ,
975998 Content : line ,
@@ -1004,7 +1027,7 @@ func parseHunks(ctx context.Context, curFile *DiffFile, maxLines, maxLineCharact
10041027 rightLine ++
10051028 if curSection == nil {
10061029 // Create a new section to represent this hunk
1007- curSection = & DiffSection { file : curFile }
1030+ curSection = newDiffSectionForDiffFile ( curFile )
10081031 curFile .Sections = append (curFile .Sections , curSection )
10091032 lastLeftIdx = - 1
10101033 }
@@ -1037,7 +1060,7 @@ func parseHunks(ctx context.Context, curFile *DiffFile, maxLines, maxLineCharact
10371060 }
10381061 if curSection == nil {
10391062 // Create a new section to represent this hunk
1040- curSection = & DiffSection { file : curFile }
1063+ curSection = newDiffSectionForDiffFile ( curFile )
10411064 curFile .Sections = append (curFile .Sections , curSection )
10421065 lastLeftIdx = - 1
10431066 }
@@ -1064,7 +1087,7 @@ func parseHunks(ctx context.Context, curFile *DiffFile, maxLines, maxLineCharact
10641087 lastLeftIdx = - 1
10651088 if curSection == nil {
10661089 // Create a new section to represent this hunk
1067- curSection = & DiffSection { file : curFile }
1090+ curSection = newDiffSectionForDiffFile ( curFile )
10681091 curFile .Sections = append (curFile .Sections , curSection )
10691092 }
10701093 curSection .Lines = append (curSection .Lines , diffLine )
@@ -1309,7 +1332,7 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
13091332 isVendored , isGenerated = attrs .GetVendored (), attrs .GetGenerated ()
13101333 language := attrs .GetLanguage ()
13111334 if language .Has () {
1312- diffFile .Language = language .Value ()
1335+ diffFile .language . value = language .Value ()
13131336 }
13141337 attrDiff = attrs .Get (attribute .Diff ).ToString ()
13151338 }
@@ -1336,24 +1359,33 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
13361359 shouldFullFileHighlight := ! setting .Git .DisableDiffHighlight && attrDiff .Value () == ""
13371360 if shouldFullFileHighlight {
13381361 if limitedContent .LeftContent != nil && limitedContent .LeftContent .buf .Len () < MaxDiffHighlightEntireFileSize {
1339- diffFile .highlightedLeftLines = highlightCodeLines (diffFile , true /* left */ , limitedContent .LeftContent .buf .Bytes ())
1362+ diffFile .highlightedLeftLines . value = highlightCodeLinesForDiffFile (diffFile , true /* left */ , limitedContent .LeftContent .buf .Bytes ())
13401363 }
13411364 if limitedContent .RightContent != nil && limitedContent .RightContent .buf .Len () < MaxDiffHighlightEntireFileSize {
1342- diffFile .highlightedRightLines = highlightCodeLines (diffFile , false /* right */ , limitedContent .RightContent .buf .Bytes ())
1365+ diffFile .highlightedRightLines . value = highlightCodeLinesForDiffFile (diffFile , false /* right */ , limitedContent .RightContent .buf .Bytes ())
13431366 }
13441367 }
13451368 }
13461369
13471370 return diff , nil
13481371}
13491372
1350- func highlightCodeLines (diffFile * DiffFile , isLeft bool , rawContent []byte ) map [int ]template.HTML {
1373+ func FillDiffFileHighlightLinesByContent (diffFile * DiffFile , left , right []byte ) {
1374+ diffFile .highlightedLeftLines .value = highlightCodeLinesForDiffFile (diffFile , true /* left */ , left )
1375+ diffFile .highlightedRightLines .value = highlightCodeLinesForDiffFile (diffFile , false /* right */ , right )
1376+ }
1377+
1378+ func highlightCodeLinesForDiffFile (diffFile * DiffFile , isLeft bool , rawContent []byte ) map [int ]template.HTML {
1379+ return highlightCodeLines (diffFile .Name , diffFile .language .value , diffFile .Sections , isLeft , rawContent )
1380+ }
1381+
1382+ func highlightCodeLines (name , lang string , sections []* DiffSection , isLeft bool , rawContent []byte ) map [int ]template.HTML {
13511383 content := util .UnsafeBytesToString (charset .ToUTF8 (rawContent , charset.ConvertOpts {}))
1352- highlightedNewContent , _ := highlight .RenderCodeFast (diffFile . Name , diffFile . Language , content )
1384+ highlightedNewContent , _ := highlight .RenderCodeFast (name , lang , content )
13531385 unsafeLines := highlight .UnsafeSplitHighlightedLines (highlightedNewContent )
13541386 lines := make (map [int ]template.HTML , len (unsafeLines ))
13551387 // only save the highlighted lines we need, but not the whole file, to save memory
1356- for _ , sec := range diffFile . Sections {
1388+ for _ , sec := range sections {
13571389 for _ , ln := range sec .Lines {
13581390 lineIdx := ln .LeftIdx
13591391 if ! isLeft {
0 commit comments