import sublime, sublime_plugin import os, sys, glob import shlex from fnmatch import fnmatch from subprocess import Popen bullet = u'\u2022' class SublimeFilesCommand(sublime_plugin.WindowCommand): def run(self, command): try: self.home except: # first time starting up. ugly, but works settings = sublime.load_settings('SublimeFiles.sublime-settings') if os.name == 'nt': self.home = 'USERPROFILE' else: self.home = 'HOME' try: os.chdir(os.path.dirname(sublime.active_window().active_view().file_name())) except: os.chdir(os.getenv(self.home)) self.bookmark = None self.term_command = settings.get('term_command') self.ignore_list = settings.get('ignore_list') self.drives = [] # for windows machines if command == 'navigate': self.open_navigator() # function for showing panel for changing directories / opening files def open_navigator(self): self.dir_files = ['[' + os.getcwdu() + ']', bullet + ' Directory actions', '..' + os.sep, '~' + os.sep] # annoying way to deal with windows if sublime.platform() == 'windows': if len(self.drives) == 0: for i in range(ord('A'), ord('Z') + 1): drive = chr(i) if (os.path.exists(drive + ':\\')): self.drives.append(drive + ':\\') self.dir_files += self.drives for element in os.listdir(os.getcwdu()): ignore_element = False for ignore_pattern in self.ignore_list: if fnmatch(element, ignore_pattern): ignore_element = True break if not ignore_element: fullpath = os.path.join(os.getcwdu(), element) if os.path.isdir(fullpath): self.dir_files.append(element + os.sep) else: self.dir_files.append(element) self.dir_files = self.dir_files[:4] + sorted(self.dir_files[4:], key=sort_files) if self.bookmark: self.dir_files.insert(2, bullet + ' To bookmark (' + self.bookmark + ')') if self.window.active_view() and self.window.active_view().file_name(): self.dir_files.insert(2, bullet + ' To current view') self.window.show_quick_panel(self.dir_files, self.handle_navigator_option, sublime.MONOSPACE_FONT) # handles user's selection from open_navigator def handle_navigator_option(self, call_value): if call_value != -1: option = self.dir_files[call_value] if call_value == 0: self.open_navigator() elif call_value == 1: self.open_directory_options() elif option == '~' + os.sep: os.chdir(os.getenv(self.home)) elif option == '..' + os.sep: os.chdir(os.path.pardir) elif sublime.platform() == 'windows' and option in self.drives: os.chdir(option) elif option == bullet + ' To current view': os.chdir(os.path.dirname(self.window.active_view().file_name())) elif option.startswith(bullet + ' To bookmark'): os.chdir(self.bookmark) else: fullpath = os.path.join(os.getcwdu(), self.dir_files[call_value]) if os.path.isdir(fullpath): # navigate to directory os.chdir(self.dir_files[call_value]) else: # open file self.window.open_file(os.path.join(os.getcwdu(), fullpath)) return self.open_navigator() # options for when a user selects current directory def open_directory_options(self): self.directory_options = [bullet + ' Add folder to project', bullet + ' Create new file', bullet + ' Create new directory', bullet + ' Set bookmark here', bullet + ' Navigate to specific directory', bullet + ' Back'] # terminal opening. only for osx/linux right now if os.name == 'posix' and self.term_command: self.directory_options.insert(0, bullet + ' Open terminal here') self.window.show_quick_panel(self.directory_options, self.handle_directory_option, sublime.MONOSPACE_FONT) # handle choice for when user selects option from current directory def handle_directory_option(self, call_value): if call_value != -1: selection = self.directory_options[call_value] if selection == bullet + ' Create new file': self.window.show_input_panel('File name: ', '', self.handle_new_file, None, None) elif selection == bullet + ' Back': self.open_navigator() elif selection == bullet + ' Set bookmark here': self.bookmark = os.getcwdu() self.open_navigator() elif selection == bullet + ' Open terminal here': command = shlex.split(str(self.term_command)) command.append(os.getcwdu()) try: Popen(command) except: sublime.error_message('Unable to open terminal') elif selection == bullet + ' Add folder to project': sublime_command_line(['-a', os.getcwdu()]) elif selection == bullet + ' Create new directory': self.window.show_input_panel('Directory name: ', '', self.handle_new_directory, None, None) elif selection == bullet + ' Navigate to specific directory': self.window.show_input_panel("Navigate to: ", os.getcwdu(), self.handle_cwd, None, None); def handle_new_file(self, file_name): if os.path.isfile(os.getcwdu() + os.sep + file_name): sublime.error_message(file_name + ' already exists') return if os.path.isdir(os.getcwdu() + os.sep + file_name): sublime.error_message(file_name + ' is already a directory') return FILE = open(os.getcwdu() + os.sep + file_name, 'a') FILE.close() self.window.open_file(os.getcwdu() + os.sep + file_name) def handle_new_directory(self, dir_name): if os.path.isfile(os.getcwdu() + os.sep + dir_name): sublime.error_message(dir_name + ' is already a file') return if os.path.isdir(os.getcwdu() + os.sep + dir_name): sublime.error_message(dir_name + ' already exists') return os.makedirs(os.getcwdu() + os.sep + dir_name) def handle_cwd(self, new_dir): try: if new_dir[0] == "~": new_dir = os.getenv(self.home) + new_dir[1:] os.chdir(new_dir) except: sublime.error_message(new_dir + " does not exist") def sort_files(filename): total_weight = 0 if filename[0] == '.': total_weight += 2 if filename[-1] == os.sep: total_weight += 1 return total_weight # hack to add folders to sidebar (stolen from wbond) def get_sublime_path(): if sublime.platform() == 'osx': return '/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl' elif sublime.platform() == 'linux': return open('/proc/self/cmdline').read().split(chr(0))[0] else: return sys.executable def sublime_command_line(args): args.insert(0, get_sublime_path()) return Popen(args)