0

Bug with auto_indent and inserting snippets

Roman Komarov 6 years ago • updated 6 years ago 1

Here is a complex bug I stumbled upon: when you recreate an indent by yourself (adding a new line, erasing inserted indent, adding your desired indent) and then insert a snippet with a newline at the end, then if there is no tabstops, then the indent is added ok, but when there are tabstops before newline, then the auto_indent is not created. And fun thing: that happens only when `auto_indent` option is enabled, if you'd disable it, there would be an automatic indent for snippet, but the bug won't be there.

Well, that's complex, but here is an example code that reproduces the problem and what you could run through ST's console:

edit = view.begin_edit("lol");view.run_command('insert', {"characters": "\n"});view.erase(edit, sublime.Region(view.line(view.sel()[0]).a, view.sel()[0].a));view.run_command('insert', {"characters": "    "});view.run_command("insert_snippet", {"contents" : "snippet: $1foo\n"});view.end_edit(edit)

Or if expanded:

edit = view.begin_edit("lol")
view.run_command('insert', {"characters": "\n"})
view.erase(edit, sublime.Region(view.line(view.sel()[0]).a, view.sel()[0].a))
view.run_command('insert', {"characters": "    "})
view.run_command("insert_snippet", {"contents" : "snippet: $1foo\n"})
view.end_edit(edit)

If you'd run it somewhere with an indent, the indent would be created at the end of the snippet when you'd `tab` to the ending tabstop. But if you'd remove the `$1` or set `"auto_indent": false`, then it would magically work.

So, as I mentioned `auto_indent` — here is an obvious workaround for this bug: wrapping the inserting and erasing characters with

view.settings().set("auto_indent",False)

and

view.settings().set("auto_indent",True)

fixes this bug, however in your plugin you should cache the current state of this settings like this:

current_auto_indent = self.view.settings().get("auto_indent")
self.view.settings().set("auto_indent",False)
# Your code that messing up with the whitespaces
self.view.settings().set("auto_indent",current_auto_indent)