Created
September 13, 2011 06:04
-
-
Save sublimator/1213230 to your computer and use it in GitHub Desktop.
BrowseDirs
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
#coding: utf8 | |
#################################### IMPORTS ################################### | |
# Std Libs | |
import os | |
import inspect | |
import functools | |
import re | |
import types | |
from os.path import ( basename, join, isdir, splitext, normpath, exists, | |
ismount ) | |
# Sublime Libs | |
import sublime | |
import sublime_plugin | |
from scheduler import scheduled, wait_on_virtual_view | |
# 3rd Party Libs | |
from directorystructures import create_directory_structure | |
################################################################################ | |
FILE = 1 | |
FOLDER = 2 | |
CMD = 3 | |
COMMANDS = {} | |
UNWANTED = ( '.jpg', '.gif', '.png', '.pyc', '.pyo', '.bin', '.o', '.so', | |
'.obj', '.lib', '.pdb', '.suo', '.ncb', '.dll', '.exe', '.zip', | |
'.tar', '.gz', '.bz2', '.tgz', '.rar' ) | |
PROJECT_TEMPLATE = """\ | |
{ | |
"folders": | |
[ | |
{ | |
"path": "${1:.}" | |
} | |
], | |
"settings": | |
{ | |
${2:"${3:key}": "${4:value}"} | |
} | |
}""" | |
################################################################################ | |
def visit_drives(c, **kw): | |
""" | |
Could be a comtypes script object: | |
from comtypes.client import CreateObject | |
fso = CreateObject('scripting.filesystemobject') | |
for d in sorted(fso.Drives, **kw): | |
c(dl + ':/') | |
""" | |
for dl in 'DEFGHZC': | |
c(dl + ':/') | |
def listdir_add_commands(folder): | |
isf = lambda p: isdir(join(folder, p)) | |
filtered_list = [f for f in os.listdir(folder) if not f.endswith(UNWANTED)] | |
display = ( ['../'] + | |
[((p + '/') if isf(p) else p) for p in sorted ( | |
filtered_list, key=isf) ] + | |
sorted(COMMANDS) ) | |
visit_drives(display.append) | |
return display | |
def browse_folder(window, folder): | |
while 1: | |
sublime.status_message(normpath(folder)) | |
d = listdir_add_commands(folder) | |
# Needed for the quick panel sometimes | |
yield scheduled.delay(0) | |
result = (yield window.quick_panel(d)) | |
fn = normpath(join(folder, d[result])) | |
if not isdir(fn): break | |
else: folder = fn | |
ret = d[result] | |
if not re.match(':[a-z_]+:', ret): | |
ret = join(folder, ret) | |
yield folder, [ret] | |
def create_dir_entry(window, folder, is_folder=0): | |
av = window.active_view() | |
default = ( 'new' if is_folder else '$1.${2:%s}' % ( | |
splitext(av.file_name())[-1] if av else 'py').lstrip('.')) | |
folder = normpath(folder) | |
msg = 'Create %s in %s:' % ('folder' if is_folder else 'file', folder) | |
while True: | |
try: | |
fn = join(folder, (yield window.input(msg, default))) | |
if is_folder: os.mkdir(fn) | |
elif not os.path.exists(fn): open(fn, 'w').close() | |
break | |
except IOError, e: | |
msg = unicode(e) | |
default = basename(fn) | |
continue | |
sublime.status_message('Created %s' % fn) | |
yield fn | |
def open_file_path(fn): | |
"Formats a path as /C/some/path/on/window/no/colon.txt" | |
fn = normpath(fn) | |
fn = re.sub('^([a-zA-Z]):', '/\\1', fn) | |
fn = re.sub(r'\\', '/', fn) | |
return fn | |
def create_dir_tree(window, folder): | |
title = 'Create Folder Structure' | |
view = (yield wait_on_virtual_view(window, title)) | |
yield create_directory_structure ( | |
view.buffer, | |
wd = folder, | |
safe = True, | |
tab_size = view.setting.tab_size ) | |
def entry_and_type(e): | |
return e, ( None if not isinstance(e, basestring) else | |
FOLDER if (isdir(e) or ismount(e)) else | |
FILE if exists(e) else CMD ) | |
def command(f): | |
if isinstance(f, types.FunctionType): | |
def wrap(f): | |
@functools.wraps(f) | |
def wrapper(*args, **kw): | |
yield f(*args, **kw) | |
return wrapper | |
f = wrap(f) | |
name = f.__name__ | |
if name.endswith('_cmd'): name = name[:-4].lower() | |
COMMANDS[':%s:' % name] = f | |
return f | |
############################### QUICK BROWSE DIR ############################### | |
class QuickBrowseDir(sublime_plugin.WindowCommand): | |
def __init__(self, window): | |
super(QuickBrowseDir, self).__init__(window) | |
for name, method in inspect.getmembers(self, inspect.ismethod): | |
if name.endswith('_cmd'): | |
command(method) | |
@scheduled(every=None) | |
def run(self, folder = None, under=False): | |
window = self.window | |
fn = window.active_view().file_name() | |
if not folder: | |
if fn: folder = os.path.dirname(fn) | |
else: folder = os.getcwd() | |
if under: | |
view = window.active_view() | |
folder = view.substr(view.sel()[0]) | |
if not os.path.exists(folder): | |
sublime.status_message("%s does not exist" % folder ) | |
raise StopIteration # ~= `return` for scheduled() | |
yield self.main_loop(window, folder) | |
def main_loop(self, window, folder): | |
folder, entries = (yield browse_folder(window, folder)) | |
while entries: | |
entry, entry_type = entry_and_type(entries.pop()) | |
if entry_type is None: break | |
elif entry_type == FILE: | |
yield window.open_file(entry) | |
elif entry_type == FOLDER: | |
folder, more = (yield browse_folder(window, entry)) | |
entries.extend(more) | |
elif entry_type == CMD: | |
entries.append( (yield COMMANDS[entry](window, folder)) ) | |
def new_cmd(self, window, folder): | |
yield create_dir_entry(window, folder) | |
def mkdir_cmd(self, window, folder): | |
yield create_dir_entry(window, folder, is_folder=1) | |
def tree_cmd(self, window, folder): | |
yield create_dir_tree(window, folder) | |
def explore_cmd(self, window, folder): | |
window.cmd.open_dir(dir=open_file_path(folder)) | |
def search_cmd(self, window, folder): | |
window.cmd.show_panel( panel = "find_in_files", | |
location = open_file_path(folder) ) | |
########################### DECORATED LIKE A GRAHAVE ########################### | |
@command | |
def project(window, folder): | |
fn = join(folder, (yield window.input ( | |
'Enter Project Name', | |
'${1:%s}.sublime-project' % basename(folder)))) | |
if not exists(fn): | |
scratch = wait_on_virtual_view ( window, | |
title = 'New Project', | |
snip = PROJECT_TEMPLATE, | |
syntax = 'JavaScript/JSON.tmLanguage') | |
with open(fn, 'w') as fh: | |
fh.write((yield scratch).buffer) | |
else: | |
yield fn | |
################################################################################ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment