sublimehq / sublime_text

Issue tracker for Sublime Text
https://www.sublimetext.com
814 stars 40 forks source link

Jump to Directory in Sidebar #5604

Open themilkman opened 2 years ago

themilkman commented 2 years ago

Problem description

(This taken from the forum and discord by @webstrand)

I’d like to have a hotkey like Ctrl+P that allows me to search for and then jump to a particular subdirectory by name in the sidebar.

Currently, I have to open a file in that directory and then use “Reveal in Sidebar”. But some directories don’t have any good files to open.

Preferred solution

see above

Alternatives

-

Additional Information

No response

janfoeh commented 8 months ago

I would like to second this feature request. This is my main annoyance these days, and I have yet to find a plugin to fill this gap.

titoBouzout commented 8 months ago

This kind of works, I think the issue is that reveal_in_side_bar command doesn't seem to allow a path argument. So you have to programatively open a file, run the command then close it which makes the API awkward to use. By adding the commands file you can use it with CTRL+SHIFT+P

Commands.sublime-commands

[
    {
        "caption": "Locate Directory on Sidebar",
        "command": "locate_directory_on_sidebar"
    }
]

locate_directory_on_sidebar.py


import os
import sublime_plugin
import sublime
import re

class locate_directory_on_sidebar(sublime_plugin.WindowCommand):

    def run(self):
        window = sublime.active_window()

        def get_project_data():
            project_data = window.project_data()
            if project_data is None or "folders" not in project_data:
                return []
            return project_data["folders"]

        def get_project_path():
            file = window.project_file_name()
            return None if file is None else os.path.dirname(file)

        def get_project_folder(folder):
            if sublime.platform() == "windows":
                if re.match(r"(^[A-Za-z]{1}:(?:\\|/))", folder) is not None:
                    return folder
            elif folder.startswith("/"):
                return folder

            path = get_project_path()
            if path is not None:
                return os.path.join(path, folder)
            return folder

        data = []
        for item in get_project_data():
            for root, subdirs, files in os.walk(get_project_folder(item["path"])):
                for dir in subdirs:
                    data.append(os.path.join(root, dir))

        def on_select(selected):
            for root, subdirs, files in os.walk(data[selected]):
                for file in files:
                    file = os.path.join(root, file)
                    window.open_file(file)
                    window.run_command("reveal_in_side_bar")
                    window.run_command("close")
                    return

        window.show_quick_panel(data, on_select)
janfoeh commented 8 months ago

@titoBouzout thanks for sharing that, I appreciate it!

I'll give it a shot; where do I put the Python file — Packages/User or any of the Lib/python3(x) directories?

janfoeh commented 8 months ago

Okay, I've tried two different ways:

  1. copying the .py to Packages/User and adding Packages/User/Command.sublime-commands
  2. copying it to Packages/locate_folder and adding Packages/locate_folder/Default.sublime-commands

Sublime picks up both on load, but fails with the same error message:

Traceback (most recent call last):
  File "/Applications/Sublime Text.app/Contents/MacOS/Lib/python38/sublime_plugin.py", line 325, in reload_plugin
    m = importlib.import_module(modulename)
  File "./python3.8/importlib/__init__.py", line 127, in import_module
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 868, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/jfoeh/Library/Application Support/Sublime Text 3/Packages/User/locate_directory_on_sidebar.py", line 1, in <module>
    class locate_directory_on_sidebar(sublime_plugin.WindowCommand):
NameError: name 'sublime_plugin' is not defined

Not sure yet where that argument is supposed to come from and why it isn't there...

titoBouzout commented 8 months ago

@janfoeh add import sublime_plugin at the top of the file

janfoeh commented 8 months ago

@titoBouzout thanks again! I also had to add import sublime, as it couldn't find that either:

NameError: global name 'sublime' is not defined

After that, it almost works — just that it uses not the root of the project in the current window, but the root of the Sublime directory:

Screenshot 2024-03-15 at 14 54 32

import sublime probably wasn't right, I guess?

titoBouzout commented 8 months ago

I updated the plugin, it should include, sublime, sublime_package, and os. I'm actually not sure how to get the root of the project. What is supposed to do is to take the folders that are opened in the sidebar and scan from there.

titoBouzout commented 8 months ago

@janfoeh there it's updated to work with projects, I haven't actually tested it with an actual project as I don't use them but I am somehow confident about it

janfoeh commented 8 months ago

@titoBouzout your updated version works like a charm! Just ten minutes and it already feels indispensible.

Thank you again for your time, this is brilliant!