Sublime Forum

How can I make open-paren a completion character?

#1

I’m trying to write a set of completions for MSBuild, which has some special “reserved properties” in the form

$(PropertyName)

like

$(MSBuildProjectDirectory)

I have other completions working, the syntax definition works, etc., but what I’m trying to do is get the open paren “(” to be a completion character so my completions will fire.

I tried adding a sublime-settings file to my project with contents like:

{ "auto_complete_triggers" : { "selector": "source.msbuild", "characters": "(" } ] }

But that didn’t work. It seems to work for other characters - almost ANY other character - but not open-paren. I tried escaping it “(”, I tried putting two characters in there “$(” and tried escaping that “$(” but that didn’t work. In fact, when I tried the two-character trigger “$(” or “$(” I could get the “$” to trigger auto-complete but never the “(”.

Is there a special trick I need to do to get open-paren to allow auto-complete?

0 Likes

#2

It’s a little confusing but I’ll try to explain what’s happening. ‘(’ is actually a keybinding in the Default Keybindings that inserts the following snippet: “($0)”. This is good because you get balanced parentheses; however, you are not directly inserting a ‘(’. That’s why that setting isn’t doing anything. However, you can get around that very easily using a quick plugin. Go to Tools > New Plugin. Replace the placeholder text with the following: [code]import sublime, sublime_plugin

class CompleteOnParensListener(sublime_plugin.EventListener):
def on_selection_modified(self,view):
sel = view.sel()[0]
if view.substr(sel.a-1) == ‘(’:
view.run_command(‘auto_complete’)[/code]

Then save it to your “Packages / User” Directory (Preferences > Show packages). You can name it whatever you want. I called it “autocomplete_on_parens.py”.

0 Likes

#3

That works perfectly! I don’t think I’d ever have guessed that, so thanks. I have it working now and it’s awesome. Thanks!

0 Likes

#4

BTW, here’s what the final version ended up being for me, in case folks are interested:

class CompleteOnPropertyListener(sublime_plugin.EventListener): def on_selection_modified(self,view): sel = view.sel()[0] if not view.match_selector(sel.a, "source.msbuild"): return ch = view.substr(sublime.Region(sel.a-2, sel.a)) if ch == '$(': view.run_command('auto_complete')

I only wanted my auto-complete to run in MSBuild files so I did that check first, and I wanted to be sure it wasn’t just any paren but a “$(” combination indicating an MSBuild property reference, so I grabbed a slightly larger substring. But it’s basically the same.

0 Likes

#5

Something odd has now started happening since the Sublime Text 2 release. I didn’t notice it happening before, though I can’t promise it wasn’t an issue.

The “on_selection_modified” event seems to happen just when the cursor moves to a location, so if you’re just scrolling around or clicking with the mouse, using this mechanism means you’ll see the autocomplete pop up seemingly at random. (It’s not random - it’s when the cursor gets positioned next to an open paren - but it’s a really odd behavior.)

Is there a different event I should be using or is there a way to check if the user was just moving the cursor around so I can skip the autocomplete?

0 Likes

#6

It appears that using “on_modified” rather than “on_selection_modified” has the desired behavior. That way it requires someone to actually press the key combo that actually indicates autocomplete should execute rather than simply placing the cursor in the spot where it would fire.

0 Likes

#7

Try on_modified rather than on_selection_modified.

Edit: oops, I’m too late :smile:

0 Likes