@@ -653,22 +653,29 @@ func (f *file) messageToSymbols(msg ir.MessageValue) []*symbol {
653653//
654654// Returns nil if no symbol is found.
655655func (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
0 commit comments