Hi,
I ONLY would like to think loudly and !!quickly!!, thus please forgive me if I miss something essential
If we’re talking “only” about to jump to the last caret position (I’d argue to listen to a selection change rather than to an actual edit, because it often occurs that one goes to somewhere else to copy a chunk of text or read something only, ergo no actual edit happens) then this could be at least a possible starting point:
Each document should store two records [last_MARKER, current_MARKER] to hold these 3 variables: - file_path (of the current doc) - current_selected_range [curRange] - range_of_visible_line_numbers [visibleRange] (first visible line number in view port (window) and length to the last visible line number)
I define the circumstance whether a caret position has to be stored in a global stack (of size 2) or not via the first visible line number and the last visible line number of the current window plus the actual line number of the caret. In other words, each caret position (line number) which is not inside of the last remembered marker's first and last visible line numbers should be a candidate for the global stack. For a selection, do set [last_MARKER] only if both line numbers (begin and end of the selection) are inside of the last remembered marker’s visibleRange.
Pseudo-Code:
+ init [last_MARKER] with defaults {for each doc}
* listen to selectionDidChange notification + get line number of the begin of the current selection [curBegLineNr] + get line number of the end of the current selection [curEndLineNr] + set [current_MARKER] to current values if [curBegLineNr] inRange [last_MARKER.visibleRange] then // save the current status only if // the line number of the end of a possible selection // is also within the last range of visible line numbers // to avoid storing if user “only” selected a // a large chunk - a next notification should handle this // or // if a doc change just happened if ([curEndLineNr] inRange [last_MARKER.visibleRange]) or (STACK.size > 0 AND STACK[0].file_path <> current_MARKER.file_path) then set [last_MARKER] to [current_MARKER] endif else // caret is outside of the last visible view port, // ergo add MARKER to global STACK set [last_MARKER] to [current_MARKER] move STACK[0] to STACK[1] and insert [last_MARKER] to STACK[0] endif
* listen to active document will be changed + move STACK[0] to STACK[1] and insert [last_MARKER] of the not yet inactive doc to STACK[0]
= navigation - Jump to last caret position A “Jump to last caret position” command should take the last inserted MARKER.file_path and MARKER.curRange to restore that doc plus caret position AND swap both entries in the STACK in order to be able to jump to and fro between the both last positions.
Remark: A stack size of 2 would have the advantage that one hasn’t to care about deletions, validations of ranges, etc. within docs, otherwise each update of the stack should check if all MARKERs are still valid.
Cheers, Hans