Sublime Forum

[solved] PhantomSet must be stored as instance variable?

#1

Hi!

This little bug cost me a fair bit of time, so I thought I’d let other people know about it.

This code doesn’t work:

# -*- encoding: utf-8 -*-

import sublime
import sublime_plugin

class TestPhantomsCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        ps = sublime.PhantomSet(self.view, 'hello world')
        ps.update([
            sublime.Phantom(sublime.Region(1), 'YES!!', sublime.LAYOUT_BLOCK)
        ])

I don’t know why, but it doesn’t: nothing gets updated, and nothing’s logged in the console. To make this work, the solution I’ve struggled to find is to set ps to be an instance variable. So, this code works:

# -*- encoding: utf-8 -*-

import sublime
import sublime_plugin

class TestPhantomsCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        self.ps = sublime.PhantomSet(self.view, 'hello world')
        self.ps.update([
            sublime.Phantom(sublime.Region(1), 'YES!!', sublime.LAYOUT_BLOCK)
        ])

(note the self.)
i’ve quickly looked in the sublime.py code, but I didn’t find anything that would explain this weird bug…

Could you guys try an tell me if it’s the same for you?

Matt

1 Like

#2

The PhantomSet implements __del__ to remove the added phantom, when it is destroyed. If you use it as a local variable it is destroyed as soon as it runs out of the scope, i.e. at the end of the method.
Therefore this is the expected behavior.

5 Likes

#3

Wow thanks @r-stein . Didn’t know about the __del__ function. I guessed it was only called when del was called on it. Thanks again!

1 Like

#4

Now that four years have passed, it would be really nice if the official documentation would mention that.

https://www.sublimetext.com/docs/api_reference.html#sublime.PhantomSet

When the PhantomSet itself is deleted, it will remove all phantoms from the view.

0 Likes