Select the types of activity you want to include in your feed.
debug: add debug score for line matches (#351)
We enrich the score of a line match with more detailed information of how it was
calculated. This is similar to what we already do on the level of file matches.
···89899090 // The higher the better. Only ranks the quality of the match
9191 // within the file, does not take rank of file into account
9292- Score float64
9292+ Score float64
9393+ DebugScore string
9494+9395 LineFragments []LineFragmentMatch
9496}
9597
+36-17
contentprovider.go
···16161717import (
1818 "bytes"
1919+ "fmt"
1920 "log"
2021 "sort"
2222+ "strings"
2123 "unicode/utf8"
2224)
2325···130132 return byteOff
131133}
132134133133-func (p *contentProvider) fillMatches(ms []*candidateMatch, numContextLines int, language string) []LineMatch {
135135+func (p *contentProvider) fillMatches(ms []*candidateMatch, numContextLines int, language string, debug bool) []LineMatch {
134136 var result []LineMatch
135137 if ms[0].fileName {
136138 // There is only "line" in a filename.
···155157156158 sects := p.docSections()
157159 for i, m := range result {
158158- result[i].Score = p.matchScore(sects, &m, language)
160160+ result[i].Score, result[i].DebugScore = p.matchScore(sects, &m, language, debug)
159161 }
160162161163 return result
···296298 return 0, false
297299}
298300299299-func (p *contentProvider) matchScore(secs []DocumentSection, m *LineMatch, language string) float64 {
300300- var maxScore float64
301301+func (p *contentProvider) matchScore(secs []DocumentSection, m *LineMatch, language string, debug bool) (float64, string) {
302302+ type debugScore struct {
303303+ score float64
304304+ what string
305305+ }
306306+307307+ score := &debugScore{}
308308+ maxScore := &debugScore{}
309309+310310+ addScore := func(what string, s float64) {
311311+ if debug {
312312+ score.what += fmt.Sprintf("%s:%f, ", what, s)
313313+ }
314314+ score.score += s
315315+ }
316316+301317 for _, f := range m.LineFragments {
302318 startBoundary := f.LineOffset < len(m.Line) && (f.LineOffset == 0 || byteClass(m.Line[f.LineOffset-1]) != byteClass(m.Line[f.LineOffset]))
303319304320 end := int(f.LineOffset) + f.MatchLength
305321 endBoundary := end > 0 && (end == len(m.Line) || byteClass(m.Line[end-1]) != byteClass(m.Line[end]))
306322307307- score := 0.0
323323+ score.score = 0
324324+ score.what = ""
325325+308326 if startBoundary && endBoundary {
309309- score = scoreWordMatch
327327+ addScore("WordMatch", scoreWordMatch)
310328 } else if startBoundary || endBoundary {
311311- score = scorePartialWordMatch
329329+ addScore("PartialWordMatch", scorePartialWordMatch)
312330 }
313331314332 if m.FileName {
···316334 startMatch := sep+1 == f.LineOffset
317335 endMatch := len(m.Line) == f.LineOffset+f.MatchLength
318336 if startMatch && endMatch {
319319- score += scoreBase
337337+ addScore("Base", scoreBase)
320338 } else if startMatch || endMatch {
321321- score += (scoreBase + scorePartialBase) / 2
339339+ addScore("EdgeBase", (scoreBase+scorePartialBase)/2)
322340 } else if sep < f.LineOffset {
323323- score += scorePartialBase
341341+ addScore("InnerBase", scorePartialBase)
324342 }
325343 } else if secIdx, ok := findSection(secs, f.Offset, uint32(f.MatchLength)); ok {
326344 sec := secs[secIdx]
327345 startMatch := sec.Start == f.Offset
328346 endMatch := sec.End == f.Offset+uint32(f.MatchLength)
329347 if startMatch && endMatch {
330330- score += scoreSymbol
348348+ addScore("Symbol", scoreSymbol)
331349 } else if startMatch || endMatch {
332332- score += (scoreSymbol + scorePartialSymbol) / 2
350350+ addScore("EdgeSymbol", (scoreSymbol+scorePartialSymbol)/2)
333351 } else {
334334- score += scorePartialSymbol
352352+ addScore("InnerSymbol", scorePartialSymbol)
335353 }
336354337355 si := f.SymbolInfo
···342360 }
343361 if si != nil {
344362 // the LineFragment may not be on a symbol, then si will be nil.
345345- score += scoreKind(language, si.Kind)
363363+ addScore(fmt.Sprintf("kind:%s:%s", language, si.Kind), scoreKind(language, si.Kind))
346364 }
347365 }
348366349349- if score > maxScore {
350350- maxScore = score
367367+ if score.score > maxScore.score {
368368+ maxScore.score = score.score
369369+ maxScore.what = score.what
351370 }
352371 }
353353- return maxScore
372372+ return maxScore.score, strings.TrimRight(maxScore.what, ", ")
354373}
355374356375// scoreKind boosts a match based on the combination of language and kind. The
···7373 After string `json:",omitempty"`
74747575 // Don't expose to caller of JSON API
7676- Score float64 `json:"-"`
7676+ Score float64 `json:"-"`
7777+ ScoreDebug string `json:"-"`
7778}
78797980// Fragment holds data of a single contiguous match within in a line