Sublime Forum

Split/iterate [regions]

#24

Second/last screenshot.


0 Likes

#25

Sorry, but I should offer the following version which prevents anything happening if you are not in a View; that is, if you are in the Find dialog, or anywhere else.

[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, "keyword", \
    sublime.HIDDEN | sublime.PERSISTENT)
view.erase_regions("edited_rgn")
return view.get_regions("edited_rgns") or ]

def showRegion(view, reg):
view.sel().clear()
view.show(reg)
view.sel().add(reg)

class ToggleEditsCommand(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
edited = adjustEdits(self.view)
if not edited:
sublime.status_message(‘No edits to show or hide.’)
return
toggled = self.view.get_regions(“toggled_edits”) or ]
if toggled:
self.view.erase_regions(“toggled_edits”)
else:
self.view.add_regions(“toggled_edits”, edited,
“keyword”, sublime.DRAW_OUTLINED)

class PrevEditLineCommand(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
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]:
showRegion(self.view, reg)
break
else:
sublime.status_message(‘No edits further up.’)

class NextEditLineCommand(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
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]:
showRegion(self.view, 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():40]
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]:
        showRegion(self.view, reg)
        break

class CaptureEditing(sublime_plugin.EventListener):
def on_modified(self, view):
# create hidden regions that mirror the edited regions
window = sublime.active_window()
curr_view = window.active_view() if window != None else None
if curr_view is None or curr_view.id() != view.id():
return
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],
“keyword”, sublime.HIDDEN | sublime.PERSISTENT)
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],
“keyword”, sublime.HIDDEN | sublime.PERSISTENT)
else:
self.prev_line = self.curr_line
if currA > 0 and sel.empty():
currA -= 1
self.lastx, self.lasty = (currA, currB)
_ = adjustEdits(view)[/code]

0 Likes

#26

My GitHub includes an icon :smile:

0 Likes

#27

Different icon - it’s a pencil :smiley: .

I shall stop now! But, of course, feedback is encouraged. Andy.


0 Likes

#28

@SimFox3
I’ve replied to your email but my responses are just sitting in my Outbox?!

You enquired about my **LastEditLine **command and I did copy this file initially to work on - but I got side-tracked and this revision doesn’t have the same feature-set. That is, it’s completely different :smiley: .

LastEditLine cycles through the last edit positions similar to the behaviour of Word (when pressing Shift F5). This was my intention, but I might revisit it once I’ve completed my AndyEdits :wink:

LastEditLine.zip (1.12 KB)*

0 Likes

#29

Someone has raised the following two issues:

[quote]
Hi, nice plugin, thanks for sharing.

I found 2 issues with it:

  1. When you change line, you need to make 2 change to trigger the edit icon on this line.
  2. When you trigger undo, the wrong edit icon is removed. To reproduce, modify 3 consecutive lines to show the edit icon on each, trigger undo -> the second to last icon is removed, not the last one. The subsequent undo work fine.

Number 2 is probably a ST2 bug, I’ve found regions in ST2 sometimes unreliable, especially with undo.[/quote]

I shall investigate these. If someone has experience with the Undo actions I will appreciate advice. I suspect it cannot be worked around; at least, not without substantial coding?

Actually, this sounds like the same issue, so if I fix the first one…

0 Likes

#30

I’ve fixed the first issue at my GitHub. I won’t post the code here, as it is now part of a package (including the icon) unless someone requests me to. This will also make the Undo behave slightly better, but I think the previously mentioned issue persists to some extent. I doubt that this can be fully overcome.

There is now an option to remove the edit history for a region (via a quick panel). This could be useful if you are performing a lot of edits on the same file and don’t wish to lose all the edit history by closing the file.

This new remove option enables you to use this package as a kind of workflow. Start different areas with a comment, so that this comment will appear as a title in the quick-panel list of edits. The continuous lines following the comment will be treated as a single edit-item. When completed, using Ctrl+Alt+D (or other shortcut) to *complete *the task. Added: Hint - you can also cut and paste the same line and it will be added as a new edit-item :sunglasses:


0 Likes

#31

I can confirm it’s fixed.

For the undo issue, I suppose only jps can give an answer…

0 Likes

#32

Undo seems to behave a little better now, as a result of the other fix. I think cutting and pasting the same content will be one way to correct edited regions, or even over-writing an area with a space or character, and then using Undo.

It just occurred to me that it *might *be useful to have another shortcut to specifically add the currently highlighted text as an edit-region. I might play with this. However, cutting and pasting achieves the same (or similar) result.

0 Likes

#33

Didn’t change anything for my test case but maybe it’s better for other test case.
Strangely, soft undo works without any issue for me.

So it looks more and more like a ST2 bug.
As jps not very active in this forum since a few weeks, anyone has it’s phone number :wink:

0 Likes

#34

I believe Undo (and other features - Duplicate, Cut, Paste) can be problematic with any plug-in. But for this simple plug-in it shouldn’t be a major concern, and most of these features seem to behave well. I find if I highlight an area, press Space and then Undo (Ctrl-Z) the whole area becomes a single edit-region. This process also removes any smaller edit regions within this larger area. In view of this, I don’t think it’s necessary for me to create a shortcut to do this (as mentioned in my previous post).

If anyone can think of something useful that might be added to this, please let me know - I might consider it :wink: . Otherwise, I think it’s complete - and I’m very pleased with it :smiley: :sunglasses:

0 Likes

#35

IMHO, it’s a major issue. I had the same issue with another plugin (Edit History).
If every time I trigger an undo (which is fairly often for me :frowning: ) it remove a line that don’t have to be removed, and keep a line that have to be removed, it quickly become a mess.

I really like this plugin, but without this issue resolved I don’t think I will use it since I’ve no confidence in it.

0 Likes

#36

I shall investigate! Is it just Undo that causes you concern/issues?

0 Likes

#37

Trying a few things with this Undo issue, including doing nothing :laughing: :

def doNothing(view): view.add_regions("doh", [sublime.Region(0, 0)], "nothing", sublime.HIDDEN)

It’s kind-of a catch-22: writing code to correct Undo, the code we write becomes the *thing *that is undone. I recall others discussing this before; hopefully someone might offer some advice based on their experience :smile:.

I’ve edited my GitHub so that the region for the currently edited line doesn’t extend beyond the end of the line. So, for example, pressing Backspace doesn’t cause the region to extend to the next line. This means that we can use, for example, Ctrl-Backspace to delete the previous word, in preference to Ctrl-Z.

0 Likes

#38

[quote=“agibsonsw”]

I shall investigate! Is it just Undo that causes you concern/issues?[/quote]

Actually yes.
I don’t have any other issue with your plugin, and this undo issue is not an issue from your plugin.

Do you mind if I try to open a new [BUG] topic about this subject ? Maybe jps will give us more info about this issue.

0 Likes

#39

That’s fine. I shall still pursue this Undo issue myself: if I can trace the “sequence of events” then there might be a way around it.

I was thinking if I store variables x, y that represent the *previous *edit position (perhaps as globals), then I can check for “undo” being pressed once so that “on the next update” - re-instate the region x,y. The difference here is that x,y would be integers, rather than reflecting part of the buffer; and this change would occur on the next update, rather than happening straight-away (and being undone!). But it would help if I fully understood the sequence of events.

Andy.

0 Likes

#40

I tried briefly to create a test case but actually found that the problem is not where I thought it was :frowning:
Not sure if it’s really a bug or simply a limitation of the current API.

What I’ve found so far:
-the problem, as you probably already found, is that an undo command trigger an on_modified event that recreate the region.
-it looks like when entering the on_modified event after an undo, the region is correct (last region is removed).
-undo command trigger an on_modified event, but soft_undo not (???)
-multi-selection edition doesn’t work ?

I wrote a plugin last week (https://github.com/bizoo/SmartCursor) that have to deal with on_modified/on_selection_modified and found this about events sequence:
When you type a char or paste from clipboard:

on_modified (23, 15)

on_selection_modified (23, 15)

When you trigger undo:

on_selection_modified (23, 14)

on_modified (23, 14)

So, maybe storing the actual view.sel() in the on_selection_modified event and compare it with the one in on_modified event could be used to identify an undo command.
If they are the same, it’s an undo, otherwise it’s an edition.

0 Likes

#41

While conceding that this is *imperfect * (flawed?) while the undo issue remains, in the meantime I’ve detoured to enable jumping to any edit in any file.

It doesn’t store multi-select edited regions currently; that is, it will only store the first region. This feature could be added at some point.


0 Likes

#42

@bizoo Please gave my latest update on GitHub a trial run, thank you :smile:

0 Likes

#43

Well there remains an issue with Undo or Soft Undo in that it might consider an area as being edited when you have undone all edits for that area. I can only suggest that others give this a trial and see whether its behaviour is acceptable to you. Bear in mind that you have the option to create or remove edit regions as you progress, although you cannot remove the most recent (the current!) edit region. (Type a character in any other region and you can then remove the previous edit region.)

I will be using this a lot myself I suspect - I like the pencil that follows along :smiley: and easily jumping between, and highlighting, edits will be very useful. (I don’t overuse Undo, as I dint moke mistusks!)

Andy.

0 Likes