I’ve not looked at your version in detail, mainly because I’ve been playing/studying this myself
. You should be able to add CE = CaptureEditing within the TextCommand as well, which will make the code easier to read. I would prefer not to maintain five separate dictionaries… but, hey!, “if it works…”
. And, like myself (and most others) it lacks commentary 
From previous posts it seems that people are keen that the edit positions should jump between files. Personally, I prefer the navigation to occur within each file separately.
I’ll post my current version out of interest/ for comparison. It ignores the Enter key as an edit position; if you are currently on an edited line it should, instead, move to a different edited line. And, most significantly, it should still highlight the *correct *edited line, even if you’ve deleted, copied, duplicated, etc., text.
[code]import sublime, sublime_plugin
POSNS = {} # Based on each view’s id, store edited positions.
# The first element stores the most recently edited line
# number, so that the same line is not saved repeatedly.
class LastEditLineCommand(sublime_plugin.TextCommand):
posn = -1 # always add 1 to this, which indexes the first
# edited position (for the current view)
def run(self, edit):
vid = self.view.id()
# if there are no edited positions stored, just return
if not POSNS.has_key(vid): return
# identify the previously edited position
self.posn = (self.posn + 1) % (len(POSNS[vid]) - 1)
# if already on the next edited line, go to the previous edit
if self.view.full_line(self.view.sel()[0]).contains(POSNS[vid]-(self.posn + 1)]):
self.posn = (self.posn + 1) % (len(POSNS[vid]) - 1)
self.view.sel().clear()
# bring the edited position into view and select the line
self.view.show(POSNS[vid]-(self.posn + 1)])
self.view.sel().add(self.view.line(POSNS[vid]-(self.posn + 1)]))
class CaptureEditing(sublime_plugin.EventListener):
def on_modified(self, view):
vid = view.id()
sel = view.sel()[0]
curr_pos = sel.end()
curr_line, _ = view.rowcol(curr_pos)
if not POSNS.has_key(vid): # if a dictionary entry doesn’t already
# exist for this view…
POSNS[vid] = [curr_line, curr_pos]
self.prev_size = view.size() # store the initial size
return
self.curr_size = view.size()
self.diff = self.curr_size - self.prev_size # has the file grown/shrunk?
for index, value in enumerate(POSNS[vid]):
if index > 0 and value > curr_pos:
# for every saved position, increase or reduce it by the
# difference in file size (but only if it’s beyond the cursor)
if self.diff > 0:
POSNS[vid][index] = min(value + self.diff, self.curr_size - 1)
# min is used in case the edited position has been deleted
elif self.diff < 0:
POSNS[vid][index] = max(value + self.diff, curr_pos)
# max is used so that we don’t go beyond the end of the file
self.prev_size = self.curr_size
# if they haven’t pressed Enter, and they are not on the same line…
if view.substr(sublime.Region(0,curr_pos))-1] != ‘\n’
and POSNS[vid][0] != curr_line:
POSNS[vid].append(curr_pos) # … store the edited position,
POSNS[vid][0] = curr_line # and update the current line
if len(POSNS[vid]) > 6: POSNS[vid].pop(1)[/code]
I need to test it a lot more, and there’s tweaks I’d like to implement. For example, because the event always runs once, the first line of the view is treated as an edit position. This doesn’t concern me too much. But I’d like it to behave a bit better in terms of deciding which edit position should be jumped too on different occasions.
I could edit it such that it wouldn’t store edit positions for the same line more than once; that is, if you edit a line, a different line, and then edit the original line again, it currently treats these as an additional edit. But I’m not sure that this should be an issue. After all, I did edit the line more than once ?!