@@ -138,4 +138,105 @@ describe('[source][lsp]', function()
138138 end , symbols [1 ].siblings )
139139 )
140140 end )
141+
142+ it (
143+ ' handles symbols with identical start positions without sorting error' ,
144+ function ()
145+ -- Make sure function type is a valid LSP symbol type so that symbols in
146+ -- mock client response will be included in `get_symbols()` result
147+ dropbar .setup ({
148+ sources = {
149+ lsp = {
150+ valid_symbols = {
151+ ' Function' , -- code = 12
152+ },
153+ },
154+ },
155+ })
156+
157+ -- Mock a client that returns symbols with identical start positions
158+ --- @diagnostic disable-next-line : assign-type-mismatch
159+ mock_client .request = function (_ , method , _ , handler )
160+ if method ~= ' textDocument/documentSymbol' then
161+ return
162+ end
163+
164+ handler (nil , {
165+ {
166+ name = ' s2' ,
167+ kind = 12 ,
168+ range = {
169+ start = { line = 5 , character = 10 },
170+ [' end' ] = { line = 8 , character = 0 },
171+ },
172+ },
173+ {
174+ name = ' s3' ,
175+ kind = 12 ,
176+ range = {
177+ start = { line = 5 , character = 10 }, -- Same position as `s2`
178+ [' end' ] = { line = 10 , character = 0 },
179+ },
180+ },
181+ {
182+ name = ' s4' ,
183+ kind = 12 ,
184+ range = {
185+ start = { line = 5 , character = 10 }, -- Same position as `s2` and `s3`
186+ [' end' ] = { line = 12 , character = 0 },
187+ },
188+ },
189+ {
190+ name = ' s1' ,
191+ kind = 12 ,
192+ range = {
193+ start = { line = 3 , character = 5 },
194+ [' end' ] = { line = 6 , character = 0 },
195+ },
196+ },
197+ }, {
198+ method = ' textDocument/documentSymbol' ,
199+ client_id = mock_client .id ,
200+ })
201+
202+ return true , 1
203+ end
204+
205+ -- Should not throw 'invalid order function for sorting' error
206+ assert .is_true (pcall (function ()
207+ -- Trigger LSP update
208+ vim .api .nvim_exec_autocmds (configs .opts .bar .update_events .buf [1 ], {
209+ buffer = 0 ,
210+ })
211+
212+ lsp_source .get_symbols (
213+ vim .api .nvim_get_current_buf (),
214+ vim .api .nvim_get_current_win (),
215+ { 6 , 0 }
216+ )
217+ end ))
218+
219+ -- Verify siblings are in correct order:
220+ -- `s1` should be the first, followed by `s2/3/4` in any order since
221+ -- they has identical positions
222+ local symbols = lsp_source .get_symbols (
223+ vim .api .nvim_get_current_buf (),
224+ vim .api .nvim_get_current_win (),
225+ { 6 , 0 }
226+ )
227+ local siblings = symbols [1 ].siblings --- @type dropbar_symbol_t[]
228+ assert .is_truthy (siblings )
229+ assert .are .equal (4 , # siblings )
230+ assert .is .same (' s1' , siblings [1 ].name )
231+ assert .are .same ({
232+ s2 = true ,
233+ s3 = true ,
234+ s4 = true ,
235+ }, {
236+ [siblings [2 ].name ] = true ,
237+ [siblings [3 ].name ] = true ,
238+ [siblings [4 ].name ] = true ,
239+ })
240+ end
241+ )
141242end )
0 commit comments