33import os .path
44import time
55import types
6- import stdlib_parser
76import struct
87import xmlrpclib
98from SimpleXMLRPCServer import SimpleXMLRPCServer
109#from pysmell import idehelper
1110#from pysmell import tags
1211from re import split
1312
13+ from rope .contrib import codeassist
14+ import rope .base .project
15+
16+ '''
17+ | | instance | class | function | module | None
18+ | local | + | + | + | + |
19+ | global | + | + | + | + |
20+ | builtin | + | + | + | |
21+ | attribute | + | + | + | + |
22+ | imported | + | + | + | + |
23+ | keyword | | | | | +
24+ | parameter_keyword | | | | | +
25+ '''
26+
27+ '''
1428type_map = {
1529str(types.ModuleType) : 1,
1630str(types.ClassType) : 2,
2438str(types.BuiltinMethodType) : 7,
2539str(types.LambdaType) : 9,
2640str(types.GeneratorType) : 10 }
41+ '''
2742
28- def type_suffix (symbols ,s ):
29- type_str = symbols [s ][0 ]
30- if type_str in type_map :
31- return '?' + str (type_map [type_str ])
43+ def type_suffix (o ):
44+ t = o .type
45+ s = o .scope
46+ if t == 'instance' :
47+ return '?' + str (5 )
48+ elif t == 'class' :
49+ return '?' + str (2 )
50+ elif t == 'function' :
51+ return '?' + str (6 )
52+ elif t == 'module' :
53+ return '?' + str (1 )
54+ elif s == 'keyword' :
55+ return ''
3256 return ''
3357
3458def _uniquify (l ):
@@ -74,13 +98,14 @@ def __call__(self,name,*args):
7498 return self .fn_dict [name ](* args )
7599
76100
77- class AsyncServer :
101+ class PyCompletionServer :
78102 def __init__ (self ,port ):
79103 # Create XMLRPC server
80104 self .timeout = 0.2
81105 self ._quit = False
82106 self .port = port
83- self .std_lib = None
107+ self .project = None
108+ self .active_path = None
84109 def run (self ):
85110 if self .port == - 1 :
86111 self .server = XmlRpcPipeServer ()
@@ -90,46 +115,43 @@ def run(self):
90115 self .server .register_introspection_functions ()
91116 #self.server.socket.settimeout(self.timeout) ##timeouts cause probs
92117 self .server .register_function (self .end ,'end' )
93- self .server .register_function (self .get_completions ,'get_completions' )
94- self .server .register_function (self .tag_gen ,'tag_gen' )
95- self .server .register_function (self .load_stdlib ,'load_stdlib' )
96- self .server .register_function (self .create_stdlib ,'create_stdlib' )
97118 self .server .register_function (self .complete_phrase ,'complete_phrase' )
98119 self .server .register_function (self .complete_tip ,'complete_tip' )
99120 while not self ._quit :
100121 self .server .handle_request ()
101- def load_stdlib (self ,path ):
102- # print 'loading lib',path
103- self .stdlib = stdlib_parser .load (path )
104- return self .stdlib != None
105- def create_stdlib (self ,path ):
106- # print 'creating',path
107- self .stdlib = stdlib_parser .create (path )
108- return self .stdlib != None
109- def complete_context (self ,path ,source ,position ):
122+ def notify_active_path (self ,path ):
123+ if self .active_path == os .path .split (path )[0 ]:
124+ return True
125+ if not os .path .exists (path ):
126+ return False
127+ fdir ,fname = os .path .split (path )
128+ self .active_path = fdir
129+ try :
130+ self .project = rope .base .project .Project (fdir )
131+ except :
132+ return False
133+ return True
134+ def complete_phrase (self ,path ,source ,position ):
110135# print 'complete context',path,position
111- pass
112- def complete_tip (self ,symbol ):
136+ if path != None :
137+ if not self .notify_active_path (path ):
138+ return []
139+ if self .project == None :
140+ return []
141+ results = codeassist .code_assist (self .project , source , position )
142+ completions = sorted ([s .name + type_suffix (s ) for s in results ])
143+ return completions
144+ def complete_tip (self ,path ,source ,position ):
113145# print 'complete tip',symbol
114- context = [s .strip () for s in symbol .split ('.' )]
115- symbol = context .pop ()
116- psymbols = self .stdlib
117- for s in context :
118- if s not in psymbols :
119- print 'symbol not found'
120- return ''
121- psymbols = psymbols [s ][- 1 ]
122- if symbol not in psymbols :
123- print 'symbol not found'
124- return ''
125- symbol_data = psymbols [symbol ]
126- result = ''
127- if symbol_data [1 ] is not None :
128- result = symbol + '(' + str (symbol_data [1 ])+ ')'
129- else :
130- if symbol_data [2 ] is None or not symbol_data [2 ].startswith (symbol + '(' ):
131- result = symbol + '(...)'
132- doc = str (symbol_data [2 ])
146+ if path != None :
147+ if not self .notify_active_path (path ):
148+ return []
149+ if self .project == None :
150+ return []
151+ calltip = codeassist .get_calltip (self .project , source , position )
152+ if calltip == None :
153+ calltip = ''
154+ doc = codeassist .get_doc (self .project , source , position )
133155 if doc is not None :
134156 lines = doc .split ('\n ' )
135157 shortened = False
@@ -142,63 +164,10 @@ def complete_tip(self,symbol):
142164 doc = doc .strip (' \t \n ' )
143165 if shortened :
144166 doc += '...'
145- result += '\n ' + doc
146- print 'result' ,result
147- return result
148- def complete_phrase (self ,phrase ):
149- # print 'complete phrase',phrase
150- context = [s .strip () for s in phrase .split ('.' )]
151- phrase = context .pop ()
152- psymbols = self .stdlib
153- for s in context :
154- if s not in psymbols :
155- print 'x' ,[]
156- return []
157- psymbols = psymbols [s ][- 1 ]
158- if type (psymbols )!= types .DictType :
159- return []
160- completions = []
161- try :
162- for s in psymbols :
163- if s .startswith (phrase ):
164- completions .append (s )
165- completions = sorted (completions )
166- print 'COMPS' ,completions
167- completions = [s + type_suffix (psymbols ,s ) for s in completions ]
168- return completions
169- except :
170- import traceback ,sys
171- traceback .print_exception (* sys .exc_info ())
172- def tool_tip (self ,function ):
173- return False
174- def tag_gen (self , projectDir ):
175- args = ['pysmell' , projectDir , '-o' , os .path .join (projectDir , 'PYSMELLTAGS' )]
176- sys .argv = args
177- tags .main ()
178- return True
179- def get_completions (self , cur_file , source , line_no , cur_col ):
180- """arguments: fullPath, origSource, lineNo, origCol, matcher
181- When visiting the file at fullPath, with edited source origSource, find a list
182- of possible completion strings for the symbol located at origCol on orgLineNo using
183- matching mode matcher"""
184- print cur_file ,line_no ,cur_col
185- if not cur_file :
186- write ('No filename - is the file saved?' )
187- return TOOLTIP
188- source = file (cur_file ,'r' ).read ()
189-
190- PYSMELLDICT = idehelper .findPYSMELLDICT (cur_file )
191- if PYSMELLDICT is None :
192- write ('No PYSMELLTAGS found - you have to generate one.' )
193- return TOOLTIP
194- print 'found dict'
195- line = source .splitlines ()[line_no - 1 ]
196- index = idehelper .findBase (line , cur_col )
197- base = line [index :cur_col ]
198-
199- options = idehelper .detectCompletionType (cur_file , source , line_no , cur_col , base , PYSMELLDICT )
200- completions = idehelper .findCompletions (base , PYSMELLDICT , options )
201- return completions
167+ calltip += '\n ' + doc
168+ if calltip == None :
169+ calltip == '<unknown function>'
170+ return calltip
202171 def end (self ):
203172 self ._quit = True
204173 return True
@@ -210,7 +179,7 @@ def cmd_err():
210179
211180if __name__ == '__main__' :
212181 if len (sys .argv )!= 2 :
213- port = - 1
182+ port = 8001
214183 else :
215184 try :
216185 port = int (sys .argv [1 ])
@@ -219,5 +188,5 @@ def cmd_err():
219188 if port < - 1 :
220189 cmd_err ()
221190
222- server = AsyncServer (port )
191+ server = PyCompletionServer (port )
223192 server .run ()
0 commit comments