@@ -2,12 +2,101 @@ local location = require("peekstack.core.location")
22
33local M = {}
44
5+ --- @alias PeekstackLspResultMapper fun ( result : any , provider : string , ctx : PeekstackProviderContext ): PeekstackLocation[]
6+
7+ --- @param symbol table
8+ --- @param uri string
9+ --- @param provider string
10+ --- @param out PeekstackLocation[]
11+ local function append_document_symbol (symbol , uri , provider , out )
12+ if type (symbol ) ~= " table" then
13+ return
14+ end
15+
16+ local range = symbol .selectionRange or symbol .range
17+ local start_pos = range and range .start
18+ local end_pos = range and range [" end" ]
19+ if start_pos and end_pos then
20+ local text = symbol .name
21+ if type (text ) ~= " string" then
22+ text = nil
23+ end
24+ if type (symbol .detail ) == " string" and symbol .detail ~= " " then
25+ if text and text ~= " " then
26+ text = string.format (" %s - %s" , text , symbol .detail )
27+ else
28+ text = symbol .detail
29+ end
30+ end
31+
32+ table.insert (out , {
33+ uri = uri ,
34+ range = range ,
35+ text = text ,
36+ kind = symbol .kind ,
37+ provider = provider ,
38+ })
39+ end
40+
41+ if vim .islist (symbol .children ) then
42+ for _ , child in ipairs (symbol .children ) do
43+ append_document_symbol (child , uri , provider , out )
44+ end
45+ end
46+ end
47+
48+ --- @param result any
49+ --- @param provider string
50+ --- @param _ctx PeekstackProviderContext
51+ --- @return PeekstackLocation[]
52+ local function default_result_mapper (result , provider , _ctx )
53+ return location .list_from_lsp (result , provider )
54+ end
55+
56+ --- @param result any
57+ --- @param provider string
58+ --- @param ctx PeekstackProviderContext
59+ --- @return PeekstackLocation[]
60+ local function document_symbol_result_mapper (result , provider , ctx )
61+ local items = {}
62+ if not result then
63+ return items
64+ end
65+
66+ local results = vim .islist (result ) and result or { result }
67+
68+ local uri
69+ if ctx .bufnr and vim .api .nvim_buf_is_valid (ctx .bufnr ) then
70+ uri = vim .uri_from_bufnr (ctx .bufnr )
71+ end
72+
73+ for _ , symbol in ipairs (results ) do
74+ if type (symbol ) == " table" and symbol .location then
75+ local loc = location .normalize (symbol .location , provider )
76+ if loc then
77+ if type (symbol .name ) == " string" and symbol .name ~= " " then
78+ loc .text = symbol .name
79+ end
80+ if type (symbol .kind ) == " number" then
81+ loc .kind = symbol .kind
82+ end
83+ table.insert (items , loc )
84+ end
85+ elseif uri then
86+ append_document_symbol (symbol , uri , provider , items )
87+ end
88+ end
89+
90+ return items
91+ end
92+
593--- @param ctx PeekstackProviderContext
694--- @param method string
795--- @param provider string
896--- @param params_modifier nil | fun ( params : table )
97+ --- @param result_mapper nil | PeekstackLspResultMapper
998--- @param cb fun ( locations : PeekstackLocation[] )
10- local function request (ctx , method , provider , params_modifier , cb )
99+ local function request (ctx , method , provider , params_modifier , result_mapper , cb )
11100 local bufnr = ctx .bufnr
12101 local clients = vim .lsp .get_clients ({ bufnr = bufnr , method = method })
13102 if not clients or vim .tbl_isempty (clients ) then
@@ -17,6 +106,7 @@ local function request(ctx, method, provider, params_modifier, cb)
17106
18107 local all_locations = {}
19108 local remaining = # clients
109+ local mapper = result_mapper or default_result_mapper
20110
21111 for _ , client in ipairs (clients ) do
22112 local params = {
@@ -31,8 +121,10 @@ local function request(ctx, method, provider, params_modifier, cb)
31121 end
32122 client :request (method , params , function (err , result )
33123 if not err and result then
34- local locs = location .list_from_lsp (result , provider )
35- vim .list_extend (all_locations , locs )
124+ local ok , locs = pcall (mapper , result , provider , ctx )
125+ if ok and type (locs ) == " table" then
126+ vim .list_extend (all_locations , locs )
127+ end
36128 end
37129 remaining = remaining - 1
38130 if remaining == 0 then
45137--- @param method string
46138--- @param provider string
47139--- @param params_modifier nil | fun ( params : table )
140+ --- @param result_mapper nil | PeekstackLspResultMapper
48141--- @return fun ( ctx : PeekstackProviderContext , cb : fun ( locations : PeekstackLocation[] ))
49- local function create_provider (method , provider , params_modifier )
142+ local function create_provider (method , provider , params_modifier , result_mapper )
50143 return function (ctx , cb )
51- request (ctx , method , provider , params_modifier , cb )
144+ request (ctx , method , provider , params_modifier , result_mapper , cb )
52145 end
53146end
54147
@@ -59,5 +152,8 @@ M.declaration = create_provider("textDocument/declaration", "lsp.declaration")
59152M .references = create_provider (" textDocument/references" , " lsp.references" , function (params )
60153 params .context = { includeDeclaration = false }
61154end )
155+ M .symbols_document = create_provider (" textDocument/documentSymbol" , " lsp.symbols_document" , function (params )
156+ params .position = nil
157+ end , document_symbol_result_mapper )
62158
63159return M
0 commit comments