I’m aware this is an extremely old discussion, but it’s a problem I’m still having and which I assume others are too. I’ve written a little plugin to make nested snippets work naturally with <tab>
as the key for both inserting snippets and advancing fields. Basically it just tries to trigger a snippet to insert, and if nothing happens, then advances to the next field instead.
complete_or_advance.py
:
import sublime
import sublime_plugin
# Attempt to trigger an exact completion (such as a snippet) and if no text was
# subsequently inserted, then advance to the next field instead. In order to
# only take precedence once already inside of a snippet, the key binding should
# appear as follows:
# { "keys": ["tab"], "command": "complete_or_advance", "context":
# [
# { "key": "has_next_field", "operator": "equal", "operand": true }
# ]
# },
def build_context(view):
w = 3
return [view.substr(sublime.Region(r.begin() - w, r.end() + w)) for r in
view.sel()]
class CompleteOrAdvanceCommand(sublime_plugin.TextCommand):
def run(self, edit):
before = build_context(self.view)
self.view.run_command("insert_best_completion", args = {"exact": True})
after = build_context(self.view)
if before == after:
self.view.run_command("next_field")
This might not be based on the most efficient way to test if a snippet has been inserted, but it’s the best I could figure out which worked. View.command_history()
didn’t seem to register commands that have been run inside of a text command, so I couldn’t use it to test if the insert_best_completion
did anything.
So that it only applies once already within a snippet, you should add the command to your keymap as follows:
{ "keys": ["tab"], "command": "complete_or_advance", "context":
[
{ "key": "has_next_field", "operator": "equal", "operand": true }
]
},