Refactor jedi-completer to use a worker thread
This commit is contained in:
parent
da46be7044
commit
eed0434e39
@ -16,8 +16,9 @@
|
||||
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import vim
|
||||
from threading import Thread, Event
|
||||
from completers.completer import Completer
|
||||
from vimsupport import PostVimMessage, CurrentLineAndColumn
|
||||
from vimsupport import CurrentLineAndColumn
|
||||
|
||||
import sys
|
||||
from os.path import join, abspath, dirname
|
||||
@ -29,40 +30,89 @@ sys.path.insert(0, join(abspath(dirname(__file__)), 'jedi'))
|
||||
from jedi import Script
|
||||
sys.path.pop(0)
|
||||
|
||||
class JediCompleter( Completer ):
|
||||
|
||||
class JediCompleter(Completer):
|
||||
"""
|
||||
A Completer that uses the Jedi completion engine
|
||||
A Completer that uses the Jedi completion engine.
|
||||
https://jedi.readthedocs.org/en/latest/
|
||||
"""
|
||||
|
||||
def __init__( self ):
|
||||
self.candidates = None
|
||||
def __init__(self):
|
||||
super(JediCompleter, self).__init__()
|
||||
self._query_ready = Event()
|
||||
self._candidates_ready = Event()
|
||||
self._query = None
|
||||
self._candidates = None
|
||||
self._exit = False
|
||||
self._start_completion_thread()
|
||||
|
||||
def SupportedFiletypes( self ):
|
||||
def _start_completion_thread(self):
|
||||
self._completion_thread = Thread(target=self.SetCandidates)
|
||||
self._completion_thread.start()
|
||||
|
||||
def SupportedFiletypes(self):
|
||||
""" Just python """
|
||||
return ['python']
|
||||
|
||||
def ShouldUseNow(self, start_column):
|
||||
""" Only use jedi-completion after a . """
|
||||
line = vim.current.line
|
||||
return len(line) >= start_column and line[start_column - 1] == '.'
|
||||
def ShouldUseNowInner(self, start_column):
|
||||
"""
|
||||
Use Jedi if we are completing an identifier immediately after a dot.
|
||||
"""
|
||||
line = str(vim.current.line)
|
||||
result = line[start_column - 1] == '.'
|
||||
return result
|
||||
|
||||
def CandidatesFromStoredRequest( self ):
|
||||
return self.candidates
|
||||
|
||||
def OnFileReadyToParse(self):
|
||||
pass
|
||||
def CandidatesForQueryAsyncInner(self, query):
|
||||
self._query = query
|
||||
self._candidates_ready.clear()
|
||||
self._query_ready.set()
|
||||
|
||||
def AsyncCandidateRequestReady(self):
|
||||
return self.candidates is not None
|
||||
def AsyncCandidateRequestReadyInner(self):
|
||||
if self._completion_thread.is_alive():
|
||||
return WaitAndClear(self._candidates_ready, timeout=0.005)
|
||||
else:
|
||||
self._start_completion_thread()
|
||||
return True
|
||||
|
||||
def CandidatesFromStoredRequest(self):
|
||||
return self.candidates
|
||||
def CandidatesFromStoredRequestInner(self):
|
||||
return self._candidates or []
|
||||
|
||||
def CandidatesForQueryAsync( self, query ):
|
||||
buffer = vim.current.buffer
|
||||
filename = buffer.name
|
||||
line, column = CurrentLineAndColumn()
|
||||
script = Script("\n".join(buffer), line + 1, column, filename)
|
||||
self.candidates = [completion.word for completion
|
||||
in script.complete() if completion.word.startswith(query)]
|
||||
def SetCandidates(self):
|
||||
while True:
|
||||
WaitAndClear(self._query_ready)
|
||||
|
||||
if self._exit:
|
||||
return
|
||||
|
||||
filename = vim.current.buffer.name
|
||||
query = self._query
|
||||
line, column = CurrentLineAndColumn()
|
||||
lines = map(str, vim.current.buffer)
|
||||
if query is not None and lines[line]:
|
||||
before, after = lines[line].rsplit('.', 1)
|
||||
lines[line] = before + '.'
|
||||
column = len(before) + 1
|
||||
|
||||
source = "\n".join(lines)
|
||||
|
||||
script = Script(source, line + 1, column, filename)
|
||||
|
||||
self._candidates = [{'word': str(completion.word),
|
||||
'menu': str(completion.description),
|
||||
'info': str(completion.doc)}
|
||||
for completion in script.complete()]
|
||||
|
||||
self._candidates_ready.set()
|
||||
|
||||
def OnInsertLeave(self):
|
||||
""" Tell the worker thread to exit """
|
||||
self._exit = True
|
||||
self._query_ready.set()
|
||||
self._candidates = None
|
||||
|
||||
|
||||
def WaitAndClear(event, timeout=None):
|
||||
ret = event.wait(timeout)
|
||||
if ret:
|
||||
event.clear()
|
||||
return ret
|
||||
|
@ -1 +0,0 @@
|
||||
Subproject commit 23f36c86d7d7c5b890fef9eb9eb46cd1fe553329
|
Loading…
x
Reference in New Issue
Block a user