#!/usr/bin/env python3 # ollie:parallel read # ollie:prompt # ## lsp_symbols # # List symbols in a file, or search workspace-wide. # # **Args**: `[path]` or `[query, "--workspace"]` # # ``` # call_tool: calls=[{tool: "lsp_symbols", args: ["/abs/path.go"]}] # call_tool: calls=[{tool: "lsp_symbols", args: ["MyFunc", "--workspace"]}] # ``` # ollie:end import os import sys sys.path.insert(0, os.path.join(os.environ['OLLIE'], 's', os.environ['OLLIE_SESSION_ID'], 't')) from _lib.lsp.client import request if len(sys.argv) < 2: print("usage: lsp_symbols [--workspace]") sys.exit(1) workspace = "--workspace" in sys.argv arg = sys.argv[1] SYMBOL_KINDS = { 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 workspace: result = request("symbols", file=arg, workspace=True, query=arg) else: filepath = os.path.abspath(arg) result = request("symbols", file=filepath, workspace=False) if not result: print("(no symbols found)") sys.exit(0) def print_symbols(symbols, indent=0): for sym in symbols: kind = SYMBOL_KINDS.get(sym.get("kind", 0), "?") name = sym.get("name", "") # DocumentSymbol has range; SymbolInformation has location if "range" in sym: ln = sym["range"]["start"]["line"] + 1 print(f"{' ' * indent}{kind:12} {name} (line {ln})") if "children" in sym: print_symbols(sym["children"], indent + 1) elif "location" in sym: uri = sym["location"].get("uri", "") path = uri[7:] if uri.startswith("file://") else uri ln = sym["location"]["range"]["start"]["line"] + 1 print(f"{kind:12} {name} {path}:{ln}") print_symbols(result)