Skip to content

Commit fd3f634

Browse files
authored
LSP fix symbol at lookup (#4151)
1 parent 29d4341 commit fd3f634

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

private/buf/buflsp/file.go

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -653,22 +653,29 @@ func (f *file) messageToSymbols(msg ir.MessageValue) []*symbol {
653653
//
654654
// Returns nil if no symbol is found.
655655
func (f *file) SymbolAt(ctx context.Context, cursor protocol.Position) *symbol {
656-
// Binary search for the symbol whose start is before or equal to cursor.
657-
idx, found := slices.BinarySearchFunc(f.symbols, cursor, func(sym *symbol, cursor protocol.Position) int {
658-
return comparePositions(sym.Range().Start, cursor)
659-
})
660-
if !found {
661-
if idx == 0 {
662-
return nil
656+
cursorLocation := f.file.InverseLocation(int(cursor.Line)+1, int(cursor.Character)+1, positionalEncoding)
657+
offset := cursorLocation.Offset
658+
659+
// Binary search for insertion point based on Start.
660+
idx, _ := slices.BinarySearchFunc(f.symbols, offset, func(sym *symbol, offset int) int {
661+
if sym.span.Start <= offset {
662+
return -1
663663
}
664-
idx--
665-
}
666-
symbol := f.symbols[idx]
667-
// Check that cursor is before the end of the symbol. Range is half-open [Start, End).
668-
if comparePositions(symbol.Range().End, cursor) < 0 {
669-
return nil
670-
}
671-
f.lsp.logger.DebugContext(ctx, "found symbol", slog.Any("symbol", symbol))
664+
return 1
665+
})
666+
// Walk backwards from symbol with Start > offset to find the smallest symbol.
667+
// This makes the assumption that overlapping spans share the same start position.
668+
// For example: the following spans A[0,10], B[0,15], C[0,20], D[20,30] and a
669+
// target offset 12, binary search returns 3 (D), and the minimum node is B.
670+
var symbol *symbol
671+
for _, before := range slices.Backward(f.symbols[:idx]) {
672+
// Offset is past the end. Range is half-open [Start, End)
673+
if offset > before.span.End {
674+
break
675+
}
676+
symbol = before
677+
}
678+
f.lsp.logger.DebugContext(ctx, "symbol at", slog.Int("line", int(cursor.Line)), slog.Int("character", int(cursor.Character)), slog.Any("symbol", symbol))
672679
return symbol
673680
}
674681

private/buf/buflsp/symbol.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ func (s *symbol) getDocsFromComments() string {
391391
}
392392

393393
// If the file is a remote dependency, link to BSR docs.
394-
if s.def.file != nil && !s.def.file.IsLocal() {
394+
if s.def != nil && s.def.file != nil && !s.def.file.IsLocal() {
395395
// In the BSR, messages, enums, and service definitions support anchor tags in the link.
396396
// Otherwise, we use the anchor for the parent type.
397397
var hasAnchor, isExtension bool

0 commit comments

Comments
 (0)