Sublime Forum

How to verify if a file is opened in preview mode?


I’d like to make my plugin more user-friendly: if the file is in preview mode, skip the rest actions.

Using “Goto Anything” menu entry and navigating files with up and down keys will fire on_load event.

Single-click on files in Side Bar will fire on_load and on_activated events (exactly same as double-click).

I searched the forum and wrote something like this:

def is_preview(self, view):
	window = view.window()
	if not window:
		return True
	return view.file_name() not in [v.file_name() for v in window.views()]

def perform_action(self, view):
	if self.is_preview(view):
	status = view.settings().get('perform_status', False)
	if status:
	view.settings().set('perform_status', True)
	# perform actions

def on_load(self, view):

def on_activated(self, view):

This works fine when: “Goto Anything” then press enter, or single-click a file in Side Bar then double-click it again. But it failed randomly when user double-click the files in Side Bar directly. It seems view.window() always returns None in on_load event (except using “Open” or “Open Recent” menu entries which fire on_activated before on_load).

Then, I changed on_load and on_activated to use set_timeout API:

# 100 failed, 200 failed sometimes
timeout = 250
def on_load(self, view):
	sublime.set_timeout(lambda: self.perform_action(view), timeout)

def on_activated(self, view):
	sublime.set_timeout(lambda: self.perform_action(view), timeout)

A 250ms delay is acceptable but not comfortable since users will open files directly in most cases.

Is there any more immediate or effective approach to handle this case?

Any comment will be appreciated, thank you.

1 Like

on_load induced by preview in goto anything
On_load is not triggered in a new view with Ctrl+N

As I understand view.window() is always not empty(on_activate or on_load). It can be empty only if you don’t use timeout. With timeout it always filled with current window.

The only one way to determine if this view is preview or not is looking for view id in sublime.active_window().views(). If there is no current - it is preview. But it works only when you use timeout. :cry:

Correct me if I wrong.