From e68b9d00a6e05b3a941f63ffb696f91e554ac5ec Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 18 Oct 2024 20:33:49 +0200 Subject: Adding upstream version 9.0.3. Signed-off-by: Daniel Baumann --- modules/indexer/code/search.go | 228 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 modules/indexer/code/search.go (limited to 'modules/indexer/code/search.go') diff --git a/modules/indexer/code/search.go b/modules/indexer/code/search.go new file mode 100644 index 0000000..f45907a --- /dev/null +++ b/modules/indexer/code/search.go @@ -0,0 +1,228 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package code + +import ( + "bytes" + "context" + "html/template" + "strings" + + "code.gitea.io/gitea/modules/highlight" + "code.gitea.io/gitea/modules/indexer/code/internal" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/services/gitdiff" +) + +// Result a search result to display +type Result struct { + 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 + +type SearchOptions = internal.SearchOptions + +func indices(content string, selectionStartIndex, selectionEndIndex int) (int, int) { + startIndex := selectionStartIndex + numLinesBefore := 0 + for ; startIndex > 0; startIndex-- { + if content[startIndex-1] == '\n' { + if numLinesBefore == 1 { + break + } + numLinesBefore++ + } + } + + endIndex := selectionEndIndex + numLinesAfter := 0 + for ; endIndex < len(content); endIndex++ { + if content[endIndex] == '\n' { + if numLinesAfter == 1 { + break + } + numLinesAfter++ + } + } + + return startIndex, endIndex +} + +func writeStrings(buf *bytes.Buffer, strs ...string) error { + for _, s := range strs { + _, err := buf.WriteString(s) + if err != nil { + return err + } + } + return nil +} + +const ( + highlightTagStart = "" + highlightTagEnd = "" +) + +func HighlightSearchResultCode(filename string, lineNums []int, highlightRanges [][3]int, code string) []ResultLine { + hcd := gitdiff.NewHighlightCodeDiff() + hcd.CollectUsedRunes(code) + startTag, endTag := hcd.NextPlaceholder(), hcd.NextPlaceholder() + hcd.PlaceholderTokenMap[startTag] = highlightTagStart + hcd.PlaceholderTokenMap[endTag] = highlightTagEnd + + // we should highlight the whole code block first, otherwise it doesn't work well with multiple line highlighting + hl, _ := highlight.Code(filename, "", code) + conv := hcd.ConvertToPlaceholders(string(hl)) + convLines := strings.Split(conv, "\n") + + // each highlightRange is of the form [line number, start pos, end pos] + for _, highlightRange := range highlightRanges { + ln, start, end := highlightRange[0], highlightRange[1], highlightRange[2] + line := convLines[ln] + if line == "" || len(line) <= start || len(line) < end { + continue + } + + sb := strings.Builder{} + count := -1 + isOpen := false + for _, r := range line { + if token, ok := hcd.PlaceholderTokenMap[r]; + // token was not found + !ok || + // token was marked as used + token == "" || + // the token is not an valid html tag emitted by chroma + !(len(token) > 6 && (token[0:5] == "