// Copyright 2017 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package search import ( "bytes" "html" gotemplate "html/template" "strings" "code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/indexer" "code.gitea.io/gitea/modules/util" ) // Result a search result to display type Result struct { Filename string HighlightClass string LineNumbers []int FormattedLines gotemplate.HTML } 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 } func searchResult(result *indexer.RepoSearchResult, startIndex, endIndex int) (*Result, error) { startLineNum := 1 + strings.Count(result.Content[:startIndex], "\n") var formattedLinesBuffer bytes.Buffer contentLines := strings.SplitAfter(result.Content[startIndex:endIndex], "\n") lineNumbers := make([]int, len(contentLines)) index := startIndex for i, line := range contentLines { var err error if index < result.EndIndex && result.StartIndex < index+len(line) && result.StartIndex < result.EndIndex { openActiveIndex := util.Max(result.StartIndex-index, 0) closeActiveIndex := util.Min(result.EndIndex-index, len(line)) err = writeStrings(&formattedLinesBuffer, `