66import os
77import json
88import io
9- from completor import Completor , vim , get
9+ from completor import Completor , vim
1010from completor .compat import to_unicode
1111
1212from . import ext
1313from .models import Initialize , DidOpen , Completion , DidChange , DidSave , \
1414 Definition , Format , Rename , Hover , Initialized , Implementation , \
1515 References , DidChangeConfiguration , Symbol , Signature , DocumentSymbol , \
16- CodeAction , CodeResolve
16+ CodeAction , CodeResolve , PrepareCallHierarchy , IncomingCalls , \
17+ OutgoingCalls
1718from .action import gen_jump_list , get_completion_word , gen_hover_doc , \
1819 filter_items , parse_symbols , rename
19- from .utils import gen_uri
20+ from .utils import gen_uri , to_filename
2021
2122logger = logging .getLogger ('completor' )
2223
@@ -30,6 +31,7 @@ def __init__(self, *args, **kwargs):
3031 self .server_cmd = None
3132 self .initialized = False
3233 self .current_id = None
34+ self .current_request_args = None
3335 self .current_options = None
3436 self .is_ext = False
3537 self .open_file_map = {}
@@ -134,6 +136,25 @@ def code_action(self, action):
134136 self .current_id = req_id
135137 return req
136138
139+ def prepare_call_hierarchy (self , args ):
140+ if not args :
141+ return ''
142+ req = self .position_request (PrepareCallHierarchy )
143+ self .current_request_args = args
144+ return req
145+
146+ def call_hierarchy (self , data , call ):
147+ try :
148+ item = json .loads (data )
149+ except Exception as e :
150+ logger .exception (e )
151+ return ''
152+
153+ c = call (item )
154+ req_id , req = c .to_request ()
155+ self .current_id = req_id
156+ return req
157+
137158 def code_action_callback (self , data ):
138159 if not data :
139160 return ''
@@ -220,6 +241,19 @@ def _gen_action_args(self, action, args):
220241 if action == b'hover' :
221242 return self .position_request (Hover )
222243
244+ if action == b'prepare_call_hierarchy' :
245+ return self .prepare_call_hierarchy (args )
246+
247+ if action == b'incoming_calls' :
248+ if not args :
249+ return ''
250+ return self .call_hierarchy (args [0 ], IncomingCalls )
251+
252+ if action == b'outgoing_calls' :
253+ if not args :
254+ return ''
255+ return self .call_hierarchy (args [0 ], OutgoingCalls )
256+
223257 handler = ext .get_action_handler (action , self .ft_orig )
224258 if handler :
225259 self .is_ext = True
@@ -229,6 +263,7 @@ def _gen_action_args(self, action, args):
229263 return ''
230264
231265 def gen_request (self , action , args ):
266+ self .current_request_args = None
232267 self .current_options = {}
233268 if args :
234269 last = args [- 1 ]
@@ -453,6 +488,54 @@ def on_hover(self, data):
453488
454489 return [gen_hover_doc (self .ft_orig , '\n \n ' .join (values ))]
455490
491+ def on_prepare_call_hierarchy (self , data ):
492+ logger .info ("prepare_call_hierarchy -> %r" , data )
493+ if not data :
494+ return []
495+
496+ if not self .current_request_args :
497+ return []
498+
499+ method = self .current_request_args [0 ]
500+
501+ items = data [0 ]
502+ if not items :
503+ return []
504+
505+ item = items [0 ]
506+
507+ try :
508+ data = json .dumps (item )
509+ except Exception as e :
510+ logger .exception (e )
511+ return []
512+
513+ return vim .Dictionary (data = [data ], action = 'do' , method = method )
514+
515+ def on_incoming_calls (self , data , direction = 'from' ):
516+ logger .info ("incoming_calls -> %r" , data )
517+ if not data :
518+ return []
519+
520+ res = []
521+ for item in data [0 ]:
522+ data = item [direction ]
523+ if direction == 'from' :
524+ start = item ['fromRanges' ][0 ]['start' ]
525+ else :
526+ start = data ['selectionRange' ]['start' ]
527+ res .append ({
528+ 'filename' : to_filename (data ['uri' ]),
529+ 'lnum' : start ['line' ] + 1 ,
530+ 'col' : start ['character' ] + 1 ,
531+ 'name' : data ['name' ],
532+ })
533+
534+ return vim .Dictionary (data = res , action = 'references' )
535+
536+ def on_outgoing_calls (self , data ):
537+ return self .on_incoming_calls (data , direction = 'to' )
538+
456539 def on_lsp_ext (self , data ):
457540 if not data or len (data ) < 3 :
458541 return []
0 commit comments