Sublime Forum

sublime_plugin.EventListener on_post_save for cloned views

#1

Hello.

Sublime Text 2.0.2, Build 2221.

  1. Create example plugin:
    import sublime, sublime_plugin

    class EventListener(sublime_plugin.EventListener):
    def on_pre_save(self, view):
    print(’[listener] pre save event’, view.id(), view.file_name())

     def on_post_save(self, view):
     	print('[listener] post save event', view.id(), view.file_name())
    
  2. Save it to User/event_listener.py.

  3. Open a duplicate view for this file – File / New view into file.

  4. Switсh to the first view tab, open console, check view ID:
    >>> view.id() 927

  5. Switсh to the second view tab, check view ID:
    >>> view.id() 929

  6. Switch to the first (origin) view tab. Save it. See in console:
    ('[listener] pre save event', 927, u'…User\\even_listener.py') … ('[listener] post save event', 927, u'…User\\even_listener.py')

  7. Swithch to the second (cloned) view tab. Save it. See in console ID of the origin view:
    ('[listener] pre save event', 927, u'…User\\even_listener.py') … ('[listener] post save event', 927, u'…User\\even_listener.py')

  8. Expect this:
    ('[listener] pre save event', 929, u'…User\\even_listener.py') … ('[listener] post save event', 929, u'…User\\even_listener.py')

In Sublime Text 3, Build 3114 is the same behavior.

So, event fired only for origin view?
How can I catch save event for every view, not only for origin?

Now I am using workaround:
view = sublime.active_window().active_view()
instead of view parameter of the event method.

0 Likes

#2

The API docs for EventListener say:

Note that many of these events are triggered by the buffer underlying the view, and thus the method is only called once, with the first view as the parameter.

As such, this is expected behaviour, which makes sense at some level since if you wanted to take some action based on a file action it (probably) does not matter how many views there are open to it. This applies to both Sublime text 2 and 3.

That said, you could do something like this (should work in both versions):

  1. Use sublime.windows () to get the list of active windows
  2. Iterate that list of windows and for each, invoke window.views () to get the list of views in that window
  3. Iterate that list of views and invoke view.buffer_id() to see which views have the same underlyng buffer ID as the one triggered in the event.

This would give you the list of all views that are currently sharing the same buffer as the one that triggered the event.

1 Like

#3

Oh, thank you.

I was read API doc many times, but forgot this note about first view event.

0 Likes