Sublime Forum

'deepcopy' not working on view.sel()

#1

Hi, I guess the answer to this will end up being more about python than about Sublime Text, but when I do

from copy import deepcopy

def some_cool_function_of_view(view):
    copy = deepcopy(view.sel())
    print(len(copy))
    view.sel().clear()
    print(len(copy))

the first and second print statements give different numbers, with the second print statement giving 0. Basically it seems that deepcopy is failing to do an actual deep copy of view.sel().

Am I seeing double, or is this a real thing? What’s the explanation?

0 Likes

#2

View.sel returns a sublime.Selection instance, which is a pseudo-collection of selections. It is iterable and indexable, but live-updating.

I don’t exactly know what deepcopy does, but the easiest way to store the current selection for later is to just run it through the list constructor, i.e. copy = list(view.sel()), as that will iterate over all selections and fetch the sublime.Region objects all at once.

2 Likes

#3

Thank you! I don’t exactly understand what list(view.sel()) does, so I am going to go with the very cautious

copy = [sublime.Region(r.a, r.b) for r in view.sel()]

for now :slight_smile:

0 Likes

#4

[sublime.Region(r.a, r.b) for r in view.sel()] is a list comprehension that creates a new list by iterating over all of the regions in the view’s selection and creates a new region based on the properties of each region it finds.

Region’s are immutable, so you could also say [r for r in view.sel()] because, being immutable, the regions don’t change (hence there is no reason to create a new one).

The list() function takes something iterable, creates a new empty list, and then iterates over each of the items in the iterable you gave it and adds it to the list.

Hence, as @FichteFoll mentioned, list(view.sel()) is the shorthand way to do this.

2 Likes

#5

Ah ok… didn’t know Regions were immutable… thank you!

0 Likes