Wow, that didn’t take long! Consecutive edited-lines will be treated as one edit:
[code]import sublime, sublime_plugin
def AdjustEdits(view):
edited = view.get_regions(“edited_rgns”) or ]
edited_last = view.get_regions(“edited_rgn”) or ]
if not edited and not edited_last:
return False
new_edits = ]
edited.extend(edited_last)
for i, r in enumerate(edited):
if i > 0 and r.begin() == prev_end:
new_edits.append(sublime.Region(prev_begin, r.end()))
else:
new_edits.append®
prev_begin, prev_end = (r.begin(), r.end())
view.add_regions("edited_rgns", new_edits, "edits", sublime.HIDDEN)
view.erase_regions("edited_rgn")
return view.get_regions("edited_rgns") or ]
class PrevEditLineCommand(sublime_plugin.TextCommand):
def run(self, edit):
vid = self.view.id()
currA = self.view.sel()[0].begin()
edited = AdjustEdits(self.view)
if not edited:
sublime.status_message(‘No edits to go to.’)
return
for reg in [r for r in reversed(edited) if r.begin() < currA]:
self.view.sel().clear()
self.view.show(reg)
self.view.sel().add(reg)
break
else:
sublime.status_message(‘No edits further up.’)
class NextEditLineCommand(sublime_plugin.TextCommand):
def run(self, edit):
vid = self.view.id()
currA = self.view.sel()[0].begin()
edited = AdjustEdits(self.view)
if not edited:
sublime.status_message(‘No edits to go to.’)
return
for reg in [r for r in edited if r.begin() > currA]:
self.view.sel().clear()
self.view.show(reg)
self.view.sel().add(reg)
break
else:
sublime.status_message(‘No edits further down.’)
class QuickEditsCommand(sublime_plugin.TextCommand):
def run(self, edit):
window = sublime.active_window()
view = window.active_view() if window != None else None
if view is None or view.id() != self.view.id():
sublime.status_message(‘Click into the view/tab first.’)
return
self.vid = self.view.id()
edited = AdjustEdits(self.view)
if not edited:
sublime.status_message(‘No edits to list.’)
return
the_edits = ]
for i, r in enumerate(edited):
curr_line, _ = self.view.rowcol(r.begin())
curr_text = self.view.substr®.strip()
if not len(curr_text):
curr_text = self.view.substr(self.view.line®).strip():40]
+ " (line)"
the_edits.append(“Line: %03d %s” % ( curr_line + 1, curr_text ))
window.show_quick_panel(the_edits, self.on_chosen)
def on_chosen(self, index):
if index == -1: return
window = sublime.active_window()
view = window.active_view() if window != None else None
if view is None or view.id() != self.vid:
sublime.status_message('You are in a different view.')
return
edited = self.view.get_regions("edited_rgns") or ]
for reg in [r for i, r in enumerate(edited) if i == index]:
self.view.sel().clear()
self.view.show(reg)
self.view.sel().add(reg)
break
class CaptureEditing(sublime_plugin.EventListener):
def on_modified(self, view):
# create hidden regions that mirror the edited regions
vid = view.id()
sel = view.sel()[0]
currA, currB = (sel.begin(), sel.end())
self.curr_line, _ = view.rowcol(currA)
if not hasattr(self, ‘prev_line’):
self.prev_line = self.curr_line
if currA > 0 and sel.empty():
currA -= 1
self.lastx, self.lasty = (currA, currB)
self.curr_edit = sublime.Region(self.lastx, self.lasty)
view.add_regions(“edited_rgn”,[self.curr_edit], “edits”, sublime.HIDDEN)
return
if self.curr_line == self.prev_line:
self.lastx = min(currA, self.lastx)
self.lasty = max(currB, self.lasty)
self.curr_edit = sublime.Region(self.lastx, self.lasty)
view.add_regions(“edited_rgn”,[self.curr_edit], “edits”, sublime.HIDDEN)
else:
self.prev_line = self.curr_line
if currA > 0 and sel.empty():
currA -= 1
self.lastx, self.lasty = (currA, currB)
_ = AdjustEdits(view)[/code]