0

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.

Baptiste Arnaud
  • 2,522
  • 3
  • 25
  • 55
  • You may want to try removing `.` from the `word_separators` setting and see where that gets you. If it helps, you may want to do it in a syntax specific setting so it doesn't cause unintended consequences elsewhere, – OdatNurd Jun 26 '17 at 16:23

1 Answers1

2

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
r-stein
  • 4,627
  • 2
  • 16
  • 27
  • Thanks for your answer. Unfortunately it doesn't working ! Since I don't really understand what's going on I can't debug this. Any idea where could be the error ? – Baptiste Arnaud Jun 26 '17 at 17:54
  • If I create a new plugin and copy the whole code there it adds auto-completion to python files and also works with `tf.` prefixed completions. What exactly does not work? Do you have any output in the ST console ``ctrl+` ``? – r-stein Jun 26 '17 at 18:12
  • console output : current triggername: 'python-calltip-call-signature' current triggername: 'python-complete-local-symbols' current triggername: 'python-complete-object-members'. No errors. I edited my question – Baptiste Arnaud Jun 26 '17 at 18:20
  • Yes it is not highlighted, but filtered and inserted correctly? You can't highlight it, only strip it from the visible text. – r-stein Jun 26 '17 at 18:46
  • The text in the view before the last `.` is extracted and stored in `trigger` (e.g. `tf.` or `tf.contrib.`). Afterwards this trigger is removed from the completions (`c[1][len(trigger):]`) and the completions list is filtered to start with that trigger (`if c[1].startswith(trigger)`) – r-stein Jun 26 '17 at 21:26