In a plugin I’m working on, I need to perform a number of replacements. I’d like to be able to undo all changes by pressing CTRL-Z once as opposed to as many times as edits made. Is this possible?
How do I group edits to make them look atomic?
Anything done within the run() method of a TextCommand will be grouped automatically.
If possible, I’d recommend structuring your plugin such that all buffer modifications are done via a TextCommand, passing any required information via parameters. As well as working properly with undo, this will also ensure it works properly with the macro system, and repeat.
I’ve come up with the following way to decouple the actual code from the TextCommand “runner”:
[code]# decorator to tie delegate and TextCommand together
expects a view instance as first arg to delegate/decorated function.
def asTextCommand(f):
def runThruTextCommand(*args, **kwargs):
i = sublimeplugin.textCommands"textCommandRunner"]
i.prime(f, args, kwargs)
args[0].runCommand(“textCommandRunner”)
return runThruTextCommand
Makes sure to run the delegate thru a TextCommand.run method
class TextCommandRunner(sublimeplugin.TextCommand):
def run(self, view, args):
if not hasattr(self, ‘f’): return
self.f(*self.args, **self.kwargs)
del self.f
def prime(self, f, args, kwargs):
self.f = f
self.args = args
self.kwargs = kwargs
A delegate
@asTextCommand
def replace(view, what, with_this):
view.runCommand(“splitSelectionIntoLines”)
for r in view.sel():
view.replace(r, re.sub(what, with_this, view.substr®))
[/code]