Sublime Forum

Syntax variable look-behind

#1

Hi,

I’m trying to do a dynamic syntax that applies a scope to a word that has been declared somewhere.

In the example below what I’m trying to do is: if a word is after “hi” once, then we apply the alex_scope scope to that word everywhere. To do so I’m trying with a regex look-behind in the variable.


%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
scope: source.alex
variables:
namee: '(?<=hi )\w+'

contexts:
main:
- match: '{{namee}}'
scope: alex_scope

But it is not working, and the word “alexo” doesn’t get the scope :frowning:
hi alexo

The reason behind this is to combine this with custom completions. So if i declare var x as myClass then I can have completions on x with the properties of myClass.

Ideas?
Thanks a lot in advance!
Alexo

0 Likes

#2
  1. This syntax is working for me
  2. you should not use look-behind pattern, because they force ST to use a less performant syntax parser
  3. It sounds like you are using the wrong way to archive what you want. If you want to add context dependant completions you should implement an EventListener and return the auto completions.
0 Likes

#3

Thanks for answering so fast! About your points:

  1. Really? I can’t make it work for me: If I type “hi alexo” the word “alexo” gets the scope, but if I type “alexo” alone it doesn’t (at least for me). And my idea was precisely to match it without the “hi”… (after been declared with “hi”). Did you do something different? I type:
   `hi alexo
    alexo` 

For me, alexo gets the scope only in the first line…
2. Fair point, happy to find another way (3rd point)
3. Thank you, I had no idea about this but I’ll start searching for EventListener completions and try to learn. Any advice to help starting would be more than welcome of course : )

0 Likes

#4
  1. If you want to archive that you should use a negative lookahead like '(?<!hi )\b\w+'

You can start with this template.

import re

import sublime
import sublime_plugin


class AutoCompleteListener(sublime_plugin.EventListener):
    def on_query_completions(self, view, prefix, locations):
        loc = locations[0]
        if not view.score_selector(loc, "source.alex"):
            return
        line_after = view.substr(sublime.Region(loc, view.line(loc).b))
        if not re.match(r"\s+as\s+myClass", line_after):
            return
        return [
            ("property_a\tmyClass", "property_a"),
            ("property_a\tmyClass", "property_a"),
            ("property_a\tmyClass", "property_a")
        ]

How to write a Sublime Text plugin: https://code.tutsplus.com/tutorials/how-to-create-a-sublime-text-2-plugin--net-22685
Sublime Python API: https://www.sublimetext.com/docs/3/api_reference.html

0 Likes

#5

Thank you very much @r-stein ! I’ve been able to do it with the EventListener following your template :smile: Super useful!

I’m using this for SQL too: Now I have completions with the columns of the table I have selected, based on its alias (that is declarated in the from statement). So for example, when I put "my_alias." I get suggestions on the columns of that specific table! I’m so much faster coding now.

Thanks again! Awesome community

1 Like