Permalink
Browse files

Hacked together a background server for pysmell - need to profile to …

…see if it's worthwhile
  • Loading branch information...
1 parent 839be41 commit a2408858966d2e133398384e36829b940c5540e9 @orestis committed Nov 7, 2008
Showing with 153 additions and 8 deletions.
  1. +1 −1 pysmell/idehelper.py
  2. +56 −0 pysmell/pysmell_client.py
  3. +86 −0 pysmell/pysmell_server.py
  4. +10 −7 pysmell/textmate.py
View
2 pysmell/idehelper.py
@@ -57,7 +57,7 @@ def findPYSMELLDICT(filename):
pathParts.pop()
else:
return None
- return PYSMELLDICT
+ return PYSMELLDICT, os.path.join(*pathParts)
def _getPathParts(path):
View
56 pysmell/pysmell_client.py
@@ -0,0 +1,56 @@
+import asyncore, asynchat, socket
+
+class client(asynchat.async_chat):
+
+ def __init__(self, filepath, source, line, col, base):
+ asynchat.async_chat.__init__(self)
+ self.filepath = filepath
+ self.source = source
+ self.line = line
+ self.col = col
+ self.base = base
+ self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.terminator = '\x00\xDE\xAD\xBE\xEF\x00'
+ self.set_terminator(self.terminator)
+ self.buffer = []
+ self.completions = None
+ self.connect( ('127.0.0.1', 8080) )
+
+
+ def respond(self, data):
+ self.push(data)
+ self.push(self.terminator)
+
+
+ def handle_connect(self):
+ self.respond(self.filepath)
+
+
+ def handle_expt(self):
+ if not self.connected:
+ self.close()
+
+
+ def collect_incoming_data (self, data):
+ self.buffer.append(data)
+
+
+ def found_terminator (self):
+ data = ''.join(self.buffer)
+ self.buffer = []
+ if data == 'NO PYSMELLTAGS':
+ self.close()
+ elif data == 'SEND SOURCE':
+ self.respond(self.source)
+ elif data == 'SEND CURSOR':
+ self.respond('%s,%s,%s' % (self.line, self.col, self.base))
+ else:
+ #data is completions
+ self.completions = eval(data) #holy security breach, batman!
+ self.close()
+
+
+if __name__ == '__main__':
+ c = http_client()
+ asyncore.loop()
+
View
86 pysmell/pysmell_server.py
@@ -0,0 +1,86 @@
+from pysmell import idehelper
+import asynchat, asyncore, socket
+
+class server(asyncore.dispatcher):
+
+ def __init__ (self, port):
+ asyncore.dispatcher.__init__ (self)
+ self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
+ self.set_reuse_addr()
+ here = ('127.0.0.1', port + 8000)
+ self.bind(here)
+ self.listen(5)
+
+ def handle_accept (self):
+ conn, addr = self.accept()
+ project_manager(conn, addr)
+
+class states(object):
+ WAITING_SOURCE = object()
+ WAITING_CURSOR = object()
+ IDLE = object()
+
+
+class project_manager(asynchat.async_chat):
+ def __init__ (self, conn, addr):
+ asynchat.async_chat.__init__ (self, conn)
+ self.terminator = '\x00\xDE\xAD\xBE\xEF\x00'
+ self.set_terminator(self.terminator)
+ self.buffer = []
+ self.state = states.IDLE
+ self.projectPath = None
+ self.pysmellDict = None
+ self.source = None
+ self.filePath = None
+
+
+ def collect_incoming_data (self, data):
+ self.buffer.append(data)
+
+
+ def respond(self, data):
+ self.push(data)
+ self.push(self.terminator)
+
+
+ def found_terminator (self):
+ data = ''.join(self.buffer)
+ self.buffer = []
+ if self.state is states.IDLE:
+ #data is the filepath
+ self.filePath = data
+ if self.pysmellDict is None:
+ PYSMELLDICT, project = idehelper.findPYSMELLDICT(self.filePath)
+ if PYSMELLDICT is None:
+ self.respond("NO PYSMELLTAGS")
+ return
+ self.projectPath = project
+ self.pysmellDict = PYSMELLDICT
+ self.state = states.WAITING_SOURCE
+ self.respond('SEND SOURCE')
+ elif self.state is states.WAITING_SOURCE:
+ #data is the source
+ self.source = data
+ self.state = states.WAITING_CURSOR
+ self.respond('SEND CURSOR')
+ elif self.state is states.WAITING_CURSOR:
+ #data is lineno, col, base
+ lineno, col, base = data.split(',')
+ options = idehelper.detectCompletionType(
+ self.filePath, self.source, int(lineno), int(col), base, self.pysmellDict)
+ print options
+ completions = idehelper.findCompletions(base, self.pysmellDict, options)
+ self.state = states.IDLE
+ self.respond(repr(completions))
+ else:
+ raise ValueError('Invalid state')
+
+
+ def handle_close(self):
+ print 'Closing'
+ self.close()
+
+if __name__ == '__main__':
+ ps = server(80)
+ asyncore.loop()
+
View
17 pysmell/textmate.py
@@ -3,7 +3,9 @@
from pysmell import idehelper
from pysmell import tags as tags_module
from pysmell import tm_dialog
-
+from pysmell import pysmell_client
+import asyncore
+from datetime import datetime
#tm_support_path = os.environ['TM_SUPPORT_PATH'] + '/lib'
#if tm_support_path not in sys.path:
@@ -27,26 +29,26 @@ def main():
line_no = int(os.environ.get("TM_LINE_NUMBER"))
cur_col = int(os.environ.get("TM_LINE_INDEX"))
result = _main(cur_file, line_no, cur_col)
+ end = datetime.now()
if result is not None:
sys.exit(result)
def _main(cur_file, line_no, cur_col):
+ start = datetime.now()
if not cur_file:
write('No filename - is the file saved?')
return TOOLTIP
source = sys.stdin.read()
- PYSMELLDICT = idehelper.findPYSMELLDICT(cur_file)
- if PYSMELLDICT is None:
- write('No PYSMELLTAGS found - you have to generate one.')
- return TOOLTIP
line = source.splitlines()[line_no - 1]
index = idehelper.findBase(line, cur_col)
base = line[index:cur_col]
- options = idehelper.detectCompletionType(cur_file, source, line_no, cur_col, base, PYSMELLDICT)
- completions = idehelper.findCompletions(base, PYSMELLDICT, options)
+ pysmellClient = pysmell_client.client(cur_file, source, line_no, cur_col, base)
+ asyncore.loop()
+ completions = pysmellClient.completions
+ end = datetime.now()
if not completions:
write('No completions found')
return TOOLTIP
@@ -68,4 +70,5 @@ def _main(cur_file, line_no, cur_col):
return TOOLTIP
if compIndex is not None:
write(completions[compIndex]['word'][len(base):])
+ print '#Took', (end-start).microseconds / 1000.0

0 comments on commit a240885

Please sign in to comment.