Sublime Forum

How do I group edits to make them look atomic?

#1

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?

0 Likes

#2

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.

0 Likes

#3

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]

0 Likes