Skip to content

Commit 6ad1121

Browse files
committed
fix: compatibility with legacy LSPs who return SymbolInformation
1 parent d5b80cf commit 6ad1121

File tree

2 files changed

+42
-30
lines changed

2 files changed

+42
-30
lines changed

lang/lsp/lsp.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,25 +180,22 @@ type TextDocumentItem struct {
180180
Definitions map[Position][]Location `json:"-"`
181181
}
182182

183-
type HierarchicalDocumentSymbol struct {
184-
Name string `json:"name"`
185-
Detail string `json:"detail,omitempty"`
186-
Kind SymbolKind `json:"kind"`
187-
Range Range `json:"range"`
188-
SelectionRange Range `json:"selectionRange"`
189-
Children []HierarchicalDocumentSymbol `json:"children,omitempty"`
190-
}
191-
192183
type DocumentSymbol struct {
193184
Name string `json:"name"`
194185
Kind SymbolKind `json:"kind"`
195186
Tags []json.RawMessage `json:"tags"`
196-
Location Location `json:"location"`
197187
Children []*DocumentSymbol `json:"children"`
198188
Text string `json:"text"`
199189
Tokens []Token `json:"tokens"`
200190
Node *sitter.Node `json:"-"`
201191
Role SymbolRole `json:"-"`
192+
193+
// Older LSPs might return SymbolInformation[] which have `Location`.
194+
// Newer LSPs return DocumentSymbol[] which have `Range` and `SelectionRange`.
195+
// ABCoder uses `Location`, and converts `Range` to `Location` when needed.
196+
Location Location `json:"location"`
197+
Range *Range `json:"range"`
198+
SelectionRange *Range `json:"selectionRange"`
202199
}
203200

204201
type TextDocumentPositionParams struct {

lang/lsp/lsp_methods.go

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package lsp
1616

1717
import (
1818
"context"
19-
"encoding/json"
2019
"fmt"
2120
"math"
2221
"os"
@@ -64,19 +63,38 @@ func (cli *LSPClient) DidOpen(ctx context.Context, file DocumentURI) (*TextDocum
6463
return f, nil
6564
}
6665

67-
func flattenHierarchicalDocumentSymbols(symbols []HierarchicalDocumentSymbol, uri DocumentURI) []DocumentSymbol {
68-
var result []DocumentSymbol
66+
func flattenDocumentSymbols(symbols []*DocumentSymbol, uri DocumentURI) []*DocumentSymbol {
67+
var result []*DocumentSymbol
6968
for _, sym := range symbols {
70-
result = append(result, DocumentSymbol{
71-
Name: sym.Name,
72-
Kind: sym.Kind,
73-
Location: Location{
69+
var location Location
70+
if sym.Range != nil {
71+
location = Location{
7472
URI: uri,
75-
Range: sym.Range,
76-
},
77-
})
73+
Range: *sym.Range,
74+
}
75+
} else {
76+
location = sym.Location
77+
}
78+
flatSymbol := DocumentSymbol{
79+
// copy
80+
Name: sym.Name,
81+
Kind: sym.Kind,
82+
Tags: sym.Tags,
83+
Text: sym.Text,
84+
Tokens: sym.Tokens,
85+
Node: sym.Node,
86+
Children: sym.Children,
87+
// new
88+
Location: location,
89+
// empty
90+
Role: 0,
91+
Range: nil,
92+
SelectionRange: nil,
93+
}
94+
result = append(result, &flatSymbol)
95+
7896
if len(sym.Children) > 0 {
79-
childSymbols := flattenHierarchicalDocumentSymbols(sym.Children, uri)
97+
childSymbols := flattenDocumentSymbols(sym.Children, uri)
8098
result = append(result, childSymbols...)
8199
}
82100
}
@@ -98,18 +116,15 @@ func (cli *LSPClient) DocumentSymbols(ctx context.Context, file DocumentURI) (ma
98116
URI: uri,
99117
},
100118
}
101-
var respHierarchical []HierarchicalDocumentSymbol
102-
if err := cli.Call(ctx, "textDocument/documentSymbol", req, &respHierarchical); err != nil {
119+
var resp []*DocumentSymbol
120+
if err := cli.Call(ctx, "textDocument/documentSymbol", req, &resp); err != nil {
103121
return nil, err
104122
}
105-
if s, err := json.MarshalIndent(respHierarchical, "", " "); err == nil {
106-
_ = os.WriteFile("docsyms_hie.json", s, 0644)
107-
}
108-
resp := flattenHierarchicalDocumentSymbols(respHierarchical, file)
123+
respFlatten := flattenDocumentSymbols(resp, file)
109124
// cache symbols
110-
f.Symbols = make(map[Range]*DocumentSymbol, len(resp))
111-
for i := range resp {
112-
s := &resp[i]
125+
f.Symbols = make(map[Range]*DocumentSymbol, len(respFlatten))
126+
for i := range respFlatten {
127+
s := respFlatten[i]
113128
f.Symbols[s.Location.Range] = s
114129
}
115130
return f.Symbols, nil

0 commit comments

Comments
 (0)