@@ -17,6 +17,7 @@ import (
1717	"code.gitea.io/gitea/modules/charset" 
1818	"code.gitea.io/gitea/modules/git" 
1919	"code.gitea.io/gitea/modules/gitrepo" 
20+ 	path_filter "code.gitea.io/gitea/modules/indexer/code/bleve/token/path" 
2021	"code.gitea.io/gitea/modules/indexer/code/internal" 
2122	indexer_internal "code.gitea.io/gitea/modules/indexer/internal" 
2223	inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve" 
@@ -53,6 +54,7 @@ type RepoIndexerData struct {
5354	RepoID     int64 
5455	CommitID   string 
5556	Content    string 
57+ 	Filename   string 
5658	Language   string 
5759	UpdatedAt  time.Time 
5860}
@@ -64,8 +66,10 @@ func (d *RepoIndexerData) Type() string {
6466
6567const  (
6668	repoIndexerAnalyzer       =  "repoIndexerAnalyzer" 
69+ 	filenameIndexerAnalyzer   =  "filenameIndexerAnalyzer" 
70+ 	filenameIndexerTokenizer  =  "filenameIndexerTokenizer" 
6771	repoIndexerDocType        =  "repoIndexerDocType" 
68- 	repoIndexerLatestVersion  =  6 
72+ 	repoIndexerLatestVersion  =  7 
6973)
7074
7175// generateBleveIndexMapping generates a bleve index mapping for the repo indexer 
@@ -79,6 +83,11 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
7983	textFieldMapping .IncludeInAll  =  false 
8084	docMapping .AddFieldMappingsAt ("Content" , textFieldMapping )
8185
86+ 	fileNamedMapping  :=  bleve .NewTextFieldMapping ()
87+ 	fileNamedMapping .IncludeInAll  =  false 
88+ 	fileNamedMapping .Analyzer  =  filenameIndexerAnalyzer 
89+ 	docMapping .AddFieldMappingsAt ("Filename" , fileNamedMapping )
90+ 
8291	termFieldMapping  :=  bleve .NewTextFieldMapping ()
8392	termFieldMapping .IncludeInAll  =  false 
8493	termFieldMapping .Analyzer  =  analyzer_keyword .Name 
@@ -90,6 +99,7 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
9099	docMapping .AddFieldMappingsAt ("UpdatedAt" , timeFieldMapping )
91100
92101	mapping  :=  bleve .NewIndexMapping ()
102+ 
93103	if  err  :=  addUnicodeNormalizeTokenFilter (mapping ); err  !=  nil  {
94104		return  nil , err 
95105	} else  if  err  :=  mapping .AddCustomAnalyzer (repoIndexerAnalyzer , map [string ]any {
@@ -100,6 +110,16 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
100110	}); err  !=  nil  {
101111		return  nil , err 
102112	}
113+ 
114+ 	if  err  :=  mapping .AddCustomAnalyzer (filenameIndexerAnalyzer , map [string ]any {
115+ 		"type" :          analyzer_custom .Name ,
116+ 		"char_filters" :  []string {},
117+ 		"tokenizer" :     unicode .Name ,
118+ 		"token_filters" : []string {unicodeNormalizeName , path_filter .Name , lowercase .Name },
119+ 	}); err  !=  nil  {
120+ 		return  nil , err 
121+ 	}
122+ 
103123	mapping .DefaultAnalyzer  =  repoIndexerAnalyzer 
104124	mapping .AddDocumentMapping (repoIndexerDocType , docMapping )
105125	mapping .AddDocumentMapping ("_all" , bleve .NewDocumentDisabledMapping ())
@@ -174,6 +194,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
174194	return  batch .Index (id , & RepoIndexerData {
175195		RepoID :    repo .ID ,
176196		CommitID :  commitSha ,
197+ 		Filename :  update .Filename ,
177198		Content :   string (charset .ToUTF8DropErrors (fileContents , charset.ConvertOpts {})),
178199		Language :  analyze .GetCodeLanguage (update .Filename , fileContents ),
179200		UpdatedAt : time .Now ().UTC (),
@@ -240,14 +261,19 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
240261		keywordQuery  query.Query 
241262	)
242263
243- 	phraseQuery  :=  bleve .NewMatchPhraseQuery (opts .Keyword )
244- 	phraseQuery .FieldVal  =  "Content" 
245- 	phraseQuery .Analyzer  =  repoIndexerAnalyzer 
246- 	keywordQuery  =  phraseQuery 
264+ 	pathQuery  :=  bleve .NewPrefixQuery (strings .ToLower (opts .Keyword ))
265+ 	pathQuery .FieldVal  =  "Filename" 
266+ 	pathQuery .SetBoost (10 )
267+ 
268+ 	contentQuery  :=  bleve .NewMatchQuery (opts .Keyword )
269+ 	contentQuery .FieldVal  =  "Content" 
270+ 
247271	if  opts .IsKeywordFuzzy  {
248- 		phraseQuery .Fuzziness  =  inner_bleve .GuessFuzzinessByKeyword (opts .Keyword )
272+ 		contentQuery .Fuzziness  =  inner_bleve .GuessFuzzinessByKeyword (opts .Keyword )
249273	}
250274
275+ 	keywordQuery  =  bleve .NewDisjunctionQuery (contentQuery , pathQuery )
276+ 
251277	if  len (opts .RepoIDs ) >  0  {
252278		repoQueries  :=  make ([]query.Query , 0 , len (opts .RepoIDs ))
253279		for  _ , repoID  :=  range  opts .RepoIDs  {
@@ -277,7 +303,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
277303
278304	from , pageSize  :=  opts .GetSkipTake ()
279305	searchRequest  :=  bleve .NewSearchRequestOptions (indexerQuery , pageSize , from , false )
280- 	searchRequest .Fields  =  []string {"Content" , "RepoID" , "Language" , "CommitID" , "UpdatedAt" }
306+ 	searchRequest .Fields  =  []string {"Content" , "Filename"  ,  " RepoID""Language" , "CommitID" , "UpdatedAt" }
281307	searchRequest .IncludeLocations  =  true 
282308
283309	if  len (opts .Language ) ==  0  {
@@ -307,6 +333,10 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
307333				endIndex  =  locationEnd 
308334			}
309335		}
336+ 		if  len (hit .Locations ["Filename" ]) >  0  {
337+ 			startIndex , endIndex  =  internal .FilenameMatchIndexPos (hit .Fields ["Content" ].(string ))
338+ 		}
339+ 
310340		language  :=  hit .Fields ["Language" ].(string )
311341		var  updatedUnix  timeutil.TimeStamp 
312342		if  t , err  :=  time .Parse (time .RFC3339 , hit .Fields ["UpdatedAt" ].(string )); err  ==  nil  {
0 commit comments