115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
// lsp_symbols — List symbols in a file, or search workspace-wide.
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"ollie/tools/lsp/internal/lsp"
|
|
"ollie/tools/lsp/internal/cmdutil"
|
|
)
|
|
|
|
func main() {
|
|
cmdutil.RunCustom(func() {
|
|
var args struct {
|
|
Path string `json:"path"`
|
|
Query string `json:"query"`
|
|
}
|
|
if err := json.NewDecoder(os.Stdin).Decode(&args); err != nil {
|
|
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
file, _ := filepath.Abs(args.Path)
|
|
workspace := args.Query != ""
|
|
|
|
result, err := lsp.ClientRequest(&lsp.BridgeRequest{
|
|
Method: "symbols",
|
|
File: file,
|
|
Query: args.Query,
|
|
Workspace: workspace,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if result == nil || string(result) == "null" {
|
|
fmt.Println("(no symbols found)")
|
|
return
|
|
}
|
|
|
|
var docSymbols []documentSymbol
|
|
if json.Unmarshal(result, &docSymbols) == nil && len(docSymbols) > 0 {
|
|
printDocSymbols(docSymbols, 0)
|
|
return
|
|
}
|
|
|
|
var wsSymbols []workspaceSymbol
|
|
if json.Unmarshal(result, &wsSymbols) == nil && len(wsSymbols) > 0 {
|
|
for _, s := range wsSymbols {
|
|
path := lsp.URIToPath(s.Location.URI)
|
|
line := s.Location.Range.Start.Line + 1
|
|
fmt.Printf("%s:%d %s [%s]\n", path, line, s.Name, symbolKind(s.Kind))
|
|
}
|
|
return
|
|
}
|
|
|
|
fmt.Println("(no symbols found)")
|
|
})
|
|
}
|
|
|
|
func printDocSymbols(symbols []documentSymbol, indent int) {
|
|
prefix := ""
|
|
for i := 0; i < indent; i++ {
|
|
prefix += " "
|
|
}
|
|
for _, s := range symbols {
|
|
line := s.Range.Start.Line + 1
|
|
fmt.Printf("%s%s L%d [%s]\n", prefix, s.Name, line, symbolKind(s.Kind))
|
|
if len(s.Children) > 0 {
|
|
printDocSymbols(s.Children, indent+1)
|
|
}
|
|
}
|
|
}
|
|
|
|
type documentSymbol struct {
|
|
Name string `json:"name"`
|
|
Kind int `json:"kind"`
|
|
Range rang `json:"range"`
|
|
Children []documentSymbol `json:"children"`
|
|
}
|
|
|
|
type workspaceSymbol struct {
|
|
Name string `json:"name"`
|
|
Kind int `json:"kind"`
|
|
Location struct {
|
|
URI string `json:"uri"`
|
|
Range rang `json:"range"`
|
|
} `json:"location"`
|
|
}
|
|
|
|
type rang struct {
|
|
Start struct {
|
|
Line int `json:"line"`
|
|
} `json:"start"`
|
|
}
|
|
|
|
func symbolKind(k int) string {
|
|
kinds := map[int]string{
|
|
1: "File", 2: "Module", 3: "Namespace", 4: "Package",
|
|
5: "Class", 6: "Method", 7: "Property", 8: "Field",
|
|
9: "Constructor", 10: "Enum", 11: "Interface", 12: "Function",
|
|
13: "Variable", 14: "Constant", 15: "String", 16: "Number",
|
|
17: "Boolean", 18: "Array", 19: "Object", 20: "Key",
|
|
21: "Null", 22: "EnumMember", 23: "Struct", 24: "Event",
|
|
25: "Operator", 26: "TypeParameter",
|
|
}
|
|
if name, ok := kinds[k]; ok {
|
|
return name
|
|
}
|
|
return fmt.Sprintf("Kind(%d)", k)
|
|
}
|