Last active
September 26, 2015 23:48
-
-
Save jbjornson/1178613 to your computer and use it in GitHub Desktop.
Display a quick panel with the other files in the directory of the current file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
@author Josh Bjornson | |
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. | |
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ | |
or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. | |
''' | |
import sublime, sublime_plugin | |
import glob, os | |
# Display a quick panel with the other files in the directory of the current file | |
# { "keys": ["ctrl+shift+o"], "command": "open_file_in_folder"} | |
# https://gist.github.com/jbjornson/1178613 | |
class OpenFileInFolderCommand(sublime_plugin.WindowCommand): | |
def run(self): | |
self.calling_view = self.window.active_view() | |
if not hasattr(self, 'excluded_extensions'): | |
settings = sublime.load_settings('Preferences.sublime-settings') | |
self.excluded_extensions = settings.get('binary_file_patterns') + settings.get('file_exclude_patterns') | |
# get the path of the file in the active view | |
current_file = self.window.active_view().file_name() | |
if not current_file: | |
current_file = os.getcwd() | |
self.stack = {} | |
self.navigate(current_file) | |
def get_directory(self, current_file): | |
path = os.path.dirname(current_file) if os.path.isfile(current_file) else current_file | |
return os.path.normpath(path) | |
def navigate(self, current_file): | |
# Iterate over the list of files and add them to the display list | |
path = self.get_directory(current_file) | |
dir_listing = glob.glob(os.path.join(path, '*')) | |
# Filter out the binary and ignored file extensions | |
for file_path in dir_listing: | |
extension = '*' + os.path.splitext(file_path)[1].lower() | |
if extension in self.excluded_extensions: | |
dir_listing.remove(file_path) | |
# Build up the file list for display | |
self.stack[current_file] = [] | |
# Add the parent directory | |
parent = os.path.abspath(os.path.join(path, os.pardir)) | |
if not os.path.samefile(path, parent): | |
self.stack[current_file].append([os.pardir, parent]) | |
# Add all the files (aside from the current) in other files in this directory | |
for (index, file_path) in enumerate(dir_listing): | |
if self.skip_file(file_path, current_file): | |
continue | |
# If this is a sub-folder then decorate the name with an ellipsis | |
label = os.path.basename(file_path) | |
if os.path.isdir(file_path): | |
label += '/' | |
self.stack[current_file].append([label, file_path]) | |
on_done = lambda i, cwd=path: self.open_selected_file(current_file, i) | |
on_selected = lambda i, cwd=path: self.show_preview(current_file, i) | |
self.window.show_quick_panel(self.stack[current_file], on_done, sublime.MONOSPACE_FONT, 0, on_selected) | |
# os.access blatantly lies and os.stat throws an exception rather than telling me I have no permission | |
# Apparently is is easier to catch failed access than check the permissions (especially on windows) | |
def skip_file(self, file_path, current_file): | |
skip = False | |
try: | |
if os.path.samefile(file_path, current_file): | |
skip = True | |
except OSError: | |
skip = True | |
return skip | |
def open_selected_file(self, path, selected_index): | |
if selected_index < 0: | |
# The user cancelled the action - give the focus back to the "calling" view | |
self.window.focus_view(self.calling_view) | |
self.calling_view = None | |
else: | |
# If the selected item is a file then open it, otherwise recursively navigate the selected directory | |
file_path = self.stack[path][selected_index][1] | |
if os.path.isfile(file_path): | |
# Open the selected file | |
self.window.open_file(file_path) | |
else: | |
# Navigate the selected directory | |
sublime.set_timeout_async(lambda s=file_path: self.navigate(s), 0) | |
def show_preview(self, path, selected_index): | |
if selected_index >= 0: | |
file_path = self.stack[path][selected_index][1] | |
if os.path.isfile(file_path): | |
self.window.open_file(file_path, sublime.TRANSIENT) | |
else: | |
self.window.focus_view(self.calling_view) |
Added support for recursing into directories and the parent
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What about a
directorys=True
option which will display all the directories in the file (at the top, with a trailing "/") and only whenTrue
(because now they are alreadylisted but you can't actually open a directory into a view). With "../" to go up a level.And then reopening the popup with the "new dir" as base.
And what about an option to recursively list all the files from the current directory (the file is in)?
(And what happens when
view.file_name() == None
? Well, besides the exception that is being raised.)