Reputation: 2750
I implemented a SublimeText autocompletion plugin:
import sublime_plugin
import sublime
tensorflow_functions = ["tf.test","tf.AggregationMethod","tf.Assert","tf.AttrValue", (etc....)]
class TensorflowAutocomplete(sublime_plugin.EventListener):
def __init__(self):
self.tf_completions = [("%s \tTensorflow" % s, s) for s in tensorflow_functions]
def on_query_completions(self, view, prefix, locations):
if view.match_selector(locations[0], 'source.python'):
return self.tf_completions
else:
return[]
It works great but the problem is when I type a "." it resets the completion suggestions.
For example I type "tf" it suggests me all my custom list but then I type "tf." it suggests me a list as I didn't type "tf" before. I want my script to take consideration of what was typed before dots.
It's hard to explain. Do you have any idea what I need to do?
EDIT :
Here's what it does:
You can see here that "tf" isn't highlighted.
Upvotes: 0
Views: 178
Reputation: 4847
Usually Sublime Text replaces everything until the last word separator (i.e. the dot) and inserts your completion text.
If you want to insert a completion with a word separator you just need to strip the content, which will not be replaced. So you just look at the line before, extract the text before the last dot, filter and strip you completions. This is my general pattern to do this:
import re
import sublime_plugin
import sublime
tensorflow_functions = ["tf.AggregationMethod()","tf.Assert()","tf.AttrValue()","tf.AttrValue.ListValue()"]
RE_TRIGGER_BEFORE = re.compile(
r"\w*(\.[\w\.]+)"
)
class TensorflowAutocomplete(sublime_plugin.EventListener):
def __init__(self):
self.tf_completions = [("%s \tTensorflow" % s, s) for s in tensorflow_functions]
def on_query_completions(self, view, prefix, locations):
loc = locations[0]
if not view.match_selector(loc, 'source.python'):
return
completions = self.tf_completions
# get the inverted line before the location
line_before_reg = sublime.Region(view.line(loc).a, loc)
line_before = view.substr(line_before_reg)[::-1]
# check if it matches the trigger
m = RE_TRIGGER_BEFORE.match(line_before)
if m:
# get the text before the .
trigger = m.group(1)[::-1]
# filter and strip the completions
completions = [
(c[0], c[1][len(trigger):]) for c in completions
if c[1].startswith(trigger)
]
return completions
Upvotes: 2