Baptiste Arnaud
Baptiste Arnaud

Reputation: 2750

Autocompletion list RESET when typing a dot on SublimeText

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:

enter image description here

You can see here that "tf" isn't highlighted.

Upvotes: 0

Views: 178

Answers (1)

r-stein
r-stein

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

Related Questions