[PORT] Fix wrong line number in code search result (gitea#29260) (#2619)
Port [Fix wrong line number in code search result (gitea#29260)](https://github.com/go-gitea/gitea/pull/29260) PS: also added [`-e`](https://git-scm.com/docs/git-grep#Documentation/git-grep.txt--e) before passing the keyword (my bad) Co-authored-by: yp05327 <576951401@qq.com> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/2619 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Co-authored-by: Shiny Nematoda <snematoda.751k2@aleeas.com> Co-committed-by: Shiny Nematoda <snematoda.751k2@aleeas.com>
This commit is contained in:
		
							parent
							
								
									79f8339c74
								
							
						
					
					
						commit
						3b2f28ff1c
					
				
					 6 changed files with 90 additions and 67 deletions
				
			
		| 
						 | 
				
			
			@ -16,14 +16,18 @@ import (
 | 
			
		|||
 | 
			
		||||
// Result a search result to display
 | 
			
		||||
type Result struct {
 | 
			
		||||
	RepoID         int64
 | 
			
		||||
	Filename       string
 | 
			
		||||
	CommitID       string
 | 
			
		||||
	UpdatedUnix    timeutil.TimeStamp
 | 
			
		||||
	Language       string
 | 
			
		||||
	Color          string
 | 
			
		||||
	LineNumbers    []int
 | 
			
		||||
	FormattedLines template.HTML
 | 
			
		||||
	RepoID      int64
 | 
			
		||||
	Filename    string
 | 
			
		||||
	CommitID    string
 | 
			
		||||
	UpdatedUnix timeutil.TimeStamp
 | 
			
		||||
	Language    string
 | 
			
		||||
	Color       string
 | 
			
		||||
	Lines       []ResultLine
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ResultLine struct {
 | 
			
		||||
	Num              int
 | 
			
		||||
	FormattedContent template.HTML
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SearchResultLanguages = internal.SearchResultLanguages
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +74,7 @@ func searchResult(result *internal.SearchResult, startIndex, endIndex int) (*Res
 | 
			
		|||
	var formattedLinesBuffer bytes.Buffer
 | 
			
		||||
 | 
			
		||||
	contentLines := strings.SplitAfter(result.Content[startIndex:endIndex], "\n")
 | 
			
		||||
	lineNumbers := make([]int, len(contentLines))
 | 
			
		||||
	lines := make([]ResultLine, 0, len(contentLines))
 | 
			
		||||
	index := startIndex
 | 
			
		||||
	for i, line := range contentLines {
 | 
			
		||||
		var err error
 | 
			
		||||
| 
						 | 
				
			
			@ -93,21 +97,29 @@ func searchResult(result *internal.SearchResult, startIndex, endIndex int) (*Res
 | 
			
		|||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		lineNumbers[i] = startLineNum + i
 | 
			
		||||
		lines = append(lines, ResultLine{Num: startLineNum + i})
 | 
			
		||||
		index += len(line)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	highlighted, _ := highlight.Code(result.Filename, "", formattedLinesBuffer.String())
 | 
			
		||||
	// we should highlight the whole code block first, otherwise it doesn't work well with multiple line highlighting
 | 
			
		||||
	hl, _ := highlight.Code(result.Filename, "", formattedLinesBuffer.String())
 | 
			
		||||
	highlightedLines := strings.Split(string(hl), "\n")
 | 
			
		||||
 | 
			
		||||
	// The lines outputted by highlight.Code might not match the original lines, because "highlight" removes the last `\n`
 | 
			
		||||
	lines = lines[:min(len(highlightedLines), len(lines))]
 | 
			
		||||
	highlightedLines = highlightedLines[:len(lines)]
 | 
			
		||||
	for i := 0; i < len(lines); i++ {
 | 
			
		||||
		lines[i].FormattedContent = template.HTML(highlightedLines[i])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &Result{
 | 
			
		||||
		RepoID:         result.RepoID,
 | 
			
		||||
		Filename:       result.Filename,
 | 
			
		||||
		CommitID:       result.CommitID,
 | 
			
		||||
		UpdatedUnix:    result.UpdatedUnix,
 | 
			
		||||
		Language:       result.Language,
 | 
			
		||||
		Color:          result.Color,
 | 
			
		||||
		LineNumbers:    lineNumbers,
 | 
			
		||||
		FormattedLines: highlighted,
 | 
			
		||||
		RepoID:      result.RepoID,
 | 
			
		||||
		Filename:    result.Filename,
 | 
			
		||||
		CommitID:    result.CommitID,
 | 
			
		||||
		UpdatedUnix: result.UpdatedUnix,
 | 
			
		||||
		Language:    result.Language,
 | 
			
		||||
		Color:       result.Color,
 | 
			
		||||
		Lines:       lines,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,14 +16,18 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
type Result struct {
 | 
			
		||||
	RepoID         int64 // ignored
 | 
			
		||||
	Filename       string
 | 
			
		||||
	CommitID       string             // branch
 | 
			
		||||
	UpdatedUnix    timeutil.TimeStamp // ignored
 | 
			
		||||
	Language       string
 | 
			
		||||
	Color          string
 | 
			
		||||
	LineNumbers    []int64
 | 
			
		||||
	FormattedLines template.HTML
 | 
			
		||||
	RepoID      int64 // ignored
 | 
			
		||||
	Filename    string
 | 
			
		||||
	CommitID    string             // branch
 | 
			
		||||
	UpdatedUnix timeutil.TimeStamp // ignored
 | 
			
		||||
	Language    string
 | 
			
		||||
	Color       string
 | 
			
		||||
	Lines       []ResultLine
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ResultLine struct {
 | 
			
		||||
	Num              int64
 | 
			
		||||
	FormattedContent template.HTML
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const pHEAD = "HEAD:"
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +50,8 @@ func NewRepoGrep(ctx context.Context, repo *repo_model.Repository, keyword strin
 | 
			
		|||
		"-n",              // line nums
 | 
			
		||||
		"-i",              // ignore case
 | 
			
		||||
		"--full-name",     // full file path, rel to repo
 | 
			
		||||
		//"--column",        // for adding better highlighting support
 | 
			
		||||
		//"--column",      // for adding better highlighting support
 | 
			
		||||
		"-e", // for queries starting with "-"
 | 
			
		||||
	).
 | 
			
		||||
		AddDynamicArguments(keyword).
 | 
			
		||||
		AddArguments("HEAD").
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +62,8 @@ func NewRepoGrep(ctx context.Context, repo *repo_model.Repository, keyword strin
 | 
			
		|||
 | 
			
		||||
	for _, block := range strings.Split(stdout, "\n\n") {
 | 
			
		||||
		res := Result{CommitID: repo.DefaultBranch}
 | 
			
		||||
 | 
			
		||||
		linenum := []int64{}
 | 
			
		||||
		code := []string{}
 | 
			
		||||
 | 
			
		||||
		for _, line := range strings.Split(block, "\n") {
 | 
			
		||||
| 
						 | 
				
			
			@ -71,18 +78,32 @@ func NewRepoGrep(ctx context.Context, repo *repo_model.Repository, keyword strin
 | 
			
		|||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				res.LineNumbers = append(res.LineNumbers, i)
 | 
			
		||||
				linenum = append(linenum, i)
 | 
			
		||||
				code = append(code, after)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if res.Filename == "" || len(code) == 0 || len(res.LineNumbers) == 0 {
 | 
			
		||||
		if res.Filename == "" || len(code) == 0 || len(linenum) == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		res.FormattedLines, res.Language = highlight.Code(res.Filename, "", strings.Join(code, "\n"))
 | 
			
		||||
		var hl template.HTML
 | 
			
		||||
 | 
			
		||||
		hl, res.Language = highlight.Code(res.Filename, "", strings.Join(code, "\n"))
 | 
			
		||||
		res.Color = enry.GetColor(res.Language)
 | 
			
		||||
 | 
			
		||||
		hlCode := strings.Split(string(hl), "\n")
 | 
			
		||||
		n := min(len(hlCode), len(linenum))
 | 
			
		||||
 | 
			
		||||
		res.Lines = make([]ResultLine, n)
 | 
			
		||||
 | 
			
		||||
		for i := 0; i < n; i++ {
 | 
			
		||||
			res.Lines[i] = ResultLine{
 | 
			
		||||
				Num:              linenum[i],
 | 
			
		||||
				FormattedContent: template.HTML(hlCode[i]),
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		data = append(data, &res)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,14 +25,16 @@ func TestNewRepoGrep(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
		expected := []*Result{
 | 
			
		||||
			{
 | 
			
		||||
				RepoID:         0,
 | 
			
		||||
				Filename:       "README.md",
 | 
			
		||||
				CommitID:       "master",
 | 
			
		||||
				UpdatedUnix:    0,
 | 
			
		||||
				Language:       "Markdown",
 | 
			
		||||
				Color:          "#083fa1",
 | 
			
		||||
				LineNumbers:    []int64{2, 3},
 | 
			
		||||
				FormattedLines: "\nDescription for repo1",
 | 
			
		||||
				RepoID:      0,
 | 
			
		||||
				Filename:    "README.md",
 | 
			
		||||
				CommitID:    "master",
 | 
			
		||||
				UpdatedUnix: 0,
 | 
			
		||||
				Language:    "Markdown",
 | 
			
		||||
				Color:       "#083fa1",
 | 
			
		||||
				Lines: []ResultLine{
 | 
			
		||||
					{Num: 2, FormattedContent: ""},
 | 
			
		||||
					{Num: 3, FormattedContent: "Description for repo1"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,20 +22,7 @@
 | 
			
		|||
				<a role="button" class="ui basic tiny button" rel="nofollow" href="{{$repo.Link}}/src/commit/{{$result.CommitID | PathEscape}}/{{.Filename | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.diff.view_file"}}</a>
 | 
			
		||||
			</h4>
 | 
			
		||||
			<div class="ui attached table segment">
 | 
			
		||||
				<div class="file-body file-code code-view">
 | 
			
		||||
					<table>
 | 
			
		||||
						<tbody>
 | 
			
		||||
							<tr>
 | 
			
		||||
								<td class="lines-num">
 | 
			
		||||
									{{range .LineNumbers}}
 | 
			
		||||
										<a href="{{$repo.Link}}/src/commit/{{$result.CommitID | PathEscape}}/{{$result.Filename | PathEscapeSegments}}#L{{.}}"><span>{{.}}</span></a>
 | 
			
		||||
									{{end}}
 | 
			
		||||
								</td>
 | 
			
		||||
								<td class="lines-code chroma"><code class="code-inner">{{.FormattedLines}}</code></td>
 | 
			
		||||
							</tr>
 | 
			
		||||
						</tbody>
 | 
			
		||||
					</table>
 | 
			
		||||
				</div>
 | 
			
		||||
				{{template "shared/searchfile" dict "RepoLink" $repo.Link "IsIndexer" true "SearchResult" .}}
 | 
			
		||||
			</div>
 | 
			
		||||
			{{template "shared/searchbottom" dict "root" $ "result" .}}
 | 
			
		||||
		</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,20 +46,7 @@
 | 
			
		|||
								<a role="button" class="ui basic tiny button" rel="nofollow" href="{{$.SourcePath}}/src/{{if $.CodeIndexerEnabled}}commit{{else}}branch{{end}}/{{PathEscape $result.CommitID}}/{{PathEscapeSegments .Filename}}">{{ctx.Locale.Tr "repo.diff.view_file"}}</a>
 | 
			
		||||
							</h4>
 | 
			
		||||
							<div class="ui attached table segment">
 | 
			
		||||
								<div class="file-body file-code code-view">
 | 
			
		||||
									<table>
 | 
			
		||||
										<tbody>
 | 
			
		||||
											<tr>
 | 
			
		||||
												<td class="lines-num">
 | 
			
		||||
													{{range .LineNumbers}}
 | 
			
		||||
														<a href="{{$.SourcePath}}/src/{{if $.CodeIndexerEnabled}}commit{{else}}branch{{end}}/{{PathEscape $result.CommitID}}/{{PathEscapeSegments $result.Filename}}#L{{.}}"><span>{{.}}</span></a>
 | 
			
		||||
													{{end}}
 | 
			
		||||
												</td>
 | 
			
		||||
												<td class="lines-code chroma"><code class="code-inner">{{.FormattedLines}}</code></td>
 | 
			
		||||
											</tr>
 | 
			
		||||
										</tbody>
 | 
			
		||||
									</table>
 | 
			
		||||
								</div>
 | 
			
		||||
								{{template "shared/searchfile" dict "RepoLink" $.SourcePath "IsIndexer" $.CodeIndexerEnabled "SearchResult" .}}
 | 
			
		||||
							</div>
 | 
			
		||||
							{{template "shared/searchbottom" dict "root" $ "result" .}}
 | 
			
		||||
						</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								templates/shared/searchfile.tmpl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								templates/shared/searchfile.tmpl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
<div class="file-body file-code code-view">
 | 
			
		||||
	<table>
 | 
			
		||||
		<tbody>
 | 
			
		||||
			{{range .SearchResult.Lines}}
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td class="lines-num">
 | 
			
		||||
						<a href="{{$.RepoLink}}/src/{{if not $.IsIndexer}}branch{{else}}commit{{end}}/{{PathEscape $.SearchResult.CommitID}}/{{PathEscapeSegments $.SearchResult.Filename}}#L{{.Num}}"><span>{{.Num}}</span></a>
 | 
			
		||||
					</td>
 | 
			
		||||
					<td class="lines-code chroma"><code class="code-inner">{{.FormattedContent}}</code></td>
 | 
			
		||||
				</tr>
 | 
			
		||||
			{{end}}
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
</div>
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue