Skip to content

Commit

Permalink
Full-file syntax highlighting for diff pages (#33766)
Browse files Browse the repository at this point in the history
Fix #33358, fix #21970

This adds a step in the `GitDiffForRender` that does syntax highlighting for the
entire file and then only references lines from that syntax highlighted
code. This allows things like multi-line comments to be syntax
highlighted correctly.

---------

Co-authored-by: wxiaoguang <[email protected]>
  • Loading branch information
dfirebaugh and wxiaoguang authored Mar 9, 2025
1 parent 6f13331 commit 3f1f808
Show file tree
Hide file tree
Showing 14 changed files with 362 additions and 324 deletions.
20 changes: 11 additions & 9 deletions modules/git/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package git
import (
"bytes"
"encoding/base64"
"errors"
"io"

"code.gitea.io/gitea/modules/typesniffer"
Expand Down Expand Up @@ -34,8 +35,9 @@ func (b *Blob) GetBlobContent(limit int64) (string, error) {
return string(buf), err
}

// GetBlobLineCount gets line count of the blob
func (b *Blob) GetBlobLineCount() (int, error) {
// GetBlobLineCount gets line count of the blob.
// It will also try to write the content to w if it's not nil, then we could pre-fetch the content without reading it again.
func (b *Blob) GetBlobLineCount(w io.Writer) (int, error) {
reader, err := b.DataAsync()
if err != nil {
return 0, err
Expand All @@ -44,20 +46,20 @@ func (b *Blob) GetBlobLineCount() (int, error) {
buf := make([]byte, 32*1024)
count := 1
lineSep := []byte{'\n'}

c, err := reader.Read(buf)
if c == 0 && err == io.EOF {
return 0, nil
}
for {
c, err := reader.Read(buf)
if w != nil {
if _, err := w.Write(buf[:c]); err != nil {
return count, err
}
}
count += bytes.Count(buf[:c], lineSep)
switch {
case err == io.EOF:
case errors.Is(err, io.EOF):
return count, nil
case err != nil:
return count, err
}
c, err = reader.Read(buf)
}
}

Expand Down
3 changes: 2 additions & 1 deletion modules/highlight/highlight.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
gohtml "html"
"html/template"
"io"
"path"
"path/filepath"
"strings"
"sync"
Expand Down Expand Up @@ -83,7 +84,7 @@ func Code(fileName, language, code string) (output template.HTML, lexerName stri
}

if lexer == nil {
if val, ok := highlightMapping[filepath.Ext(fileName)]; ok {
if val, ok := highlightMapping[path.Ext(fileName)]; ok {
// use mapped value to find lexer
lexer = lexers.Get(val)
}
Expand Down
3 changes: 1 addition & 2 deletions routers/api/v1/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -1591,8 +1591,7 @@ func GetPullRequestFiles(ctx *context.APIContext) {
maxLines := setting.Git.MaxGitDiffLines

// FIXME: If there are too many files in the repo, may cause some unpredictable issues.
// FIXME: it doesn't need to call "GetDiff" to do various parsing and highlighting
diff, err := gitdiff.GetDiff(ctx, baseGitRepo,
diff, err := gitdiff.GetDiffForAPI(ctx, baseGitRepo,
&gitdiff.DiffOptions{
BeforeCommitID: startCommitID,
AfterCommitID: endCommitID,
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/blame.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func RefBlame(ctx *context.Context) {
return
}

ctx.Data["NumLines"], err = blob.GetBlobLineCount()
ctx.Data["NumLines"], err = blob.GetBlobLineCount(nil)
if err != nil {
ctx.NotFound(err)
return
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func Diff(ctx *context.Context) {
maxLines, maxFiles = -1, -1
}

diff, err := gitdiff.GetDiff(ctx, gitRepo, &gitdiff.DiffOptions{
diff, err := gitdiff.GetDiffForRender(ctx, gitRepo, &gitdiff.DiffOptions{
AfterCommitID: commitID,
SkipTo: ctx.FormString("skip-to"),
MaxLines: maxLines,
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ func PrepareCompareDiff(

fileOnly := ctx.FormBool("file-only")

diff, err := gitdiff.GetDiff(ctx, ci.HeadGitRepo,
diff, err := gitdiff.GetDiffForRender(ctx, ci.HeadGitRepo,
&gitdiff.DiffOptions{
BeforeCommitID: beforeCommitID,
AfterCommitID: headCommitID,
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
diffOptions.BeforeCommitID = startCommitID
}

diff, err := gitdiff.GetDiff(ctx, gitRepo, diffOptions, files...)
diff, err := gitdiff.GetDiffForRender(ctx, gitRepo, diffOptions, files...)
if err != nil {
ctx.ServerError("GetDiff", err)
return
Expand Down
Loading

0 comments on commit 3f1f808

Please sign in to comment.