Sublime Forum

Opening a file's location under tab context

#1

To create new options under tab context (for opening a file’s location, and copy file path), I did something like this and added it to $env:APPDATA\Sublime Text 3\Packages\User\Tab Context.sublime-menu:

[
  {
    "command": "open_dir",
    "args": {"file": "$file_name","dir": "$file_path"},
    "caption": "Open Containing Folder"
  },
  {
    "command": "copy_path",
    "caption": "Copy File Path"
  }
]

The problem however is, if I right click an inactive tab, then select “Open Containing Folder”, it still opens the active tab file’s location. How do I make it open the inactive tab’s file location instead?

Did a bit of Google-Fu and saw there is a tab_control class, but I couldn’t really piece it together.

Any pointers is highly appreciated.

Thanks!

0 Likes

#2

I have a custom plugin below to provide this functionality:

import sublime
import sublime_plugin
from os import path
from difflib import unified_diff

def get_view(active_view, **kwargs):
    view = active_view
    if 'group' in kwargs and 'index' in kwargs:
        view = view.window().views_in_group(kwargs['group'])[kwargs['index']]
    return view

class CopyFilePathCommand(sublime_plugin.TextCommand):
    def run(self, edit, **kwargs):
        get_view(self.view, **kwargs).run_command('copy_path')
    
    def is_enabled(self, **kwargs):
        file_path = get_view(self.view, **kwargs).file_name()
        return isinstance(file_path, str)
    
    def is_visible(self, **kwargs):
        return True

class OpenContainingFolderFromTabCommand(sublime_plugin.TextCommand):
    def run(self, edit, **kwargs):
        view = get_view(self.view, **kwargs)
        self.view.window().focus_view(view)
        
        file_path = view.file_name()
        folder = path.dirname(file_path)
        
        args = { 'dir': '$file_path', 'file': '$file_name' }
        if not path.isfile(file_path):
            del args['file']
        self.view.window().run_command('open_dir', args)
        self.view.window().focus_view(self.view)
    
    def is_enabled(self, **kwargs):
        file_path = get_view(self.view, **kwargs).file_name()
        if file_path is None:
            return False
        folder = path.dirname(file_path)
        return file_path is not None and path.isdir(folder)
    
    def is_visible(self, **kwargs):
        return True

class DiffViewsCommand(sublime_plugin.TextCommand):
    def get_lines_for_view(self, view):
        for line in view.lines(sublime.Region(0, view.size())):
            yield view.substr(line) + '\n'
    
    def run(self, edit, **kwargs):
        view = get_view(self.view, **kwargs)
        views = None
        #if view.id() == self.view.id():
        #    views = self.view.window().views()[-2:]
        #else:
        views = [view, self.view]
        
        view = self.view.window().new_file()
        
        for line in unified_diff(list(self.get_lines_for_view(views[0])), list(self.get_lines_for_view(views[1])), fromfile=views[0].file_name() or views[0].name() or 'fromfile', tofile=views[1].file_name() or views[1].name() or 'tofile'):
            view.run_command('append', { 'characters': line })
        view.assign_syntax('Packages/Diff/Diff.sublime-syntax')
    
    def is_enabled(self, **kwargs):
        return self.is_visible(**kwargs)
    
    def is_visible(self, **kwargs):
        view = get_view(self.view, **kwargs)
        return view.id() != self.view.id()

and the following override for Packages/Default/Tab Context.sublime-menu:

[
    { "command": "close_by_index", "args": { "group": -1, "index": -1 }, "caption": "Close" },
    { "command": "close_others_by_index", "args": { "group": -1, "index": -1 }, "caption": "Close Other Tabs" },
    { "command": "close_to_right_by_index", "args": { "group": -1, "index": -1 }, "caption": "Close Tabs to the Right" },
    { "caption": "-" },
    { "command": "new_file", "caption": "New File" },
    { "command": "prompt_open_file", "caption": "Open File" },
    { "caption": "-" },
    { "command": "open_containing_folder_from_tab", "args": { "group": -1, "index": -1 }, "caption": "Open Containing Folder…" },
    { "command": "copy_file_path", "args": { "group": -1, "index": -1 }, "caption": "Copy File Path" },
    //{ "command": "reveal_in_side_bar_from_tab", "args": { "group": -1, "index": -1 }, "caption": "Reveal in Side Bar" }
    { "command": "diff_views", "args": { "group": -1, "index": -1 }, "caption": "Diff With Current View" },
]

The idea is that, if you specify the group and index args, these will be automatically populated with the correct values corresponding to the tab for which the context menu was opened. Then, one can use custom commands to execute the real underlying functionality on the correct tab/view instance. In some cases, the underlying functionality makes use of window level commands, so I temporarily switch the active view.

3 Likes

#3

Thank you Keith, worked like a charm. I really appreciate the help.

0 Likes