Sublime Forum

How To: Preview Multiple Files?

#1

I’m writing a plugin, and want to preview two files side-by-side when scrolling through a quick_view list.

This works fine for a single file preview (this code would be in the on_changed function passed to the quick_view):

self.preview = self.window.open_file(
    file_desc,
    sublime.TRANSIENT | sublime.ENCODED_POSITION)

But if I want to change the layout to have 2 groups, then preview a second file in the new group, then my plugin is terminated.

self.window.set_layout(
    {"cols": [0.0, 0.5, 1.0],
     "rows": [0.0, 1.0],
     "cells": [0, 0, 1, 1], [1, 0, 2, 1]]})
self.preview = self.window.open_file(
    file_desc1,
    flags=sublime.TRANSIENT | sublime.ENCODED_POSITION)
self.preview = self.window.open_file(
    file_desc2,
    flags=sublime.TRANSIENT | sublime.ENCODED_POSITION | sublime.FORCE_GROUP,
    group=1)

I suspect this is something to do with the quick_view being associated with a specific view, and doing anything with another view terminates the quick_view. But that’s pure conjecture.

I’ve tried various things to try and work this out, and as you can see my digging has led me to some undocumented options: “sublime.FORCE_GROUP” and “group=1”, but nothing seems to let me put a preview in group 1 while keeping the quick_view active.

Any help/advice greatly appreciated.

0 Likes

#2

I consider this to be a bug, which I also encountered in FileHistory. The workaround is to re-open the quick panel when you open any kind of view in a different group than the one the quick panel was opened in.

0 Likes

#3

Aw, that’s a shame.

Does that leave you with a glitch while the quick panel is closed then re-opened?

I suppose I’ll raise on the issues list, unless someone already has.

0 Likes

#4

On trying to raise the issue with Sublime, I did a thorough search, and it looks like a similar problem was raised that ought to fix this issue:

github.com/SublimeTextIssues/Core/issues/489

But with the sublime.KEEP_OPEN_ON_FOCUS_LOST flag, it’s not clear how you should return focus to the quick panel when opening file previews.

I’ve raised Issue #1041 on GitHub.

0 Likes

#5

Posting it here as well for good measure, this is working code:

[code]import sublime
import sublime_plugin

class ViewFinder(sublime_plugin.EventListener):
_instance = None

def __init__(self, *args, **kwargs):
    self.__class__._instance = self
    self._listening = False

def on_activated(self, view):
    if self._listening and view.settings().get('is_widget'):
        self._listening = False
        self.cb(view)

@classmethod
def instance(cls):
    if cls._instance:
        return cls._instance
    else:
        return cls()

def start_listen(self, cb):
    self.cb = cb
    self._listening = True

class TestCommandCommand(sublime_plugin.WindowCommand):
# Testing this plugin requires these 2 files, and also files with the “.formatted”
# suffix to be present on the filesystem…
OPTIONS = ‘/var/tmp/file1’, ‘/var/tmp/file2’]

def run(self):
    # Side-by-side preview
    self.window.set_layout(
        {"cols": [0.0, 0.5, 1.0],
         "rows": [0.0, 1.0],
         "cells": [0, 0, 1, 1], [1, 0, 2, 1]]}
    )
    self.qpanel_group = self.window.active_group()
    print("active group", self.qpanel_group)

    ViewFinder.instance().start_listen(self.quick_panel_found)
    self.window.show_quick_panel(
        self.OPTIONS,
        self.no_op,
        sublime.MONOSPACE_FONT | sublime.KEEP_OPEN_ON_FOCUS_LOST,
        0,
        self.preview_file
    )

def quick_panel_found(self, view):
    self.qpanel = view
    print(self.qpanel, self.qpanel.id())
    self.qpanel.run_command("insert", {"characters": "t"})

def preview_file(self, index):
    file_base = self.OPTIONS[index]
    left_file = file_base + ':10'
    right_file = file_base + '.formatted:10'

    self.window.open_file(
        left_file,
        flags=sublime.TRANSIENT | sublime.ENCODED_POSITION | sublime.FORCE_GROUP,
        group=(self.qpanel_group - 1) * -1  # focus the other group first
    )
    self.window.open_file(
        right_file,
        flags=sublime.TRANSIENT | sublime.ENCODED_POSITION | sublime.FORCE_GROUP,
        group=self.qpanel_group
    )
    self.window.focus_group(self.qpanel_group)
    self.window.focus_view(self.qpanel)

def no_op(self, index):
    pass

[/code]

I’m getting the quick panel’s view handle using a small “hack” that is enabled by event hooks being invoked on all view objects, not just those that can contain files and are in window.views().
Then I focus the group the panel was opened in before focusing the actual panel. It doesn’t work if the group is not focused.

0 Likes