feat(SublimeText2.WebPackages): cache packages
This commit is contained in:
@@ -0,0 +1,462 @@
|
||||
#aponxi v0.6.0
|
||||
import sublime
|
||||
import sys
|
||||
from os import path
|
||||
import os
|
||||
from subprocess import Popen, PIPE
|
||||
from sublime_plugin import TextCommand
|
||||
from sublime_plugin import WindowCommand
|
||||
import sublime_plugin
|
||||
import time
|
||||
import functools
|
||||
|
||||
settings = sublime.load_settings('CoffeeScript.sublime-settings')
|
||||
|
||||
|
||||
def run(cmd, args=[], source="", cwd=None, env=None):
|
||||
if not type(args) is list:
|
||||
args = [args]
|
||||
if sys.platform == "win32":
|
||||
proc = Popen([cmd] + args, env=env, cwd=cwd, stdout=PIPE, stdin=PIPE, stderr=PIPE, shell=True)
|
||||
stat = proc.communicate(input=source.encode('utf-8'))
|
||||
else:
|
||||
if env is None:
|
||||
env = {"PATH": settings.get('binDir', '/usr/local/bin')}
|
||||
if source == "":
|
||||
command = [cmd] + args
|
||||
else:
|
||||
command = [cmd] + args + [source]
|
||||
# print "Debug - coffee command: "
|
||||
# print command
|
||||
proc = Popen(command, env=env, cwd=cwd, stdout=PIPE, stderr=PIPE)
|
||||
stat = proc.communicate()
|
||||
okay = proc.returncode == 0
|
||||
return {"okay": okay, "out": stat[0].decode('utf-8'), "err": stat[1].decode('utf-8')}
|
||||
|
||||
|
||||
def brew(args, source):
|
||||
if sys.platform == "win32":
|
||||
args.append("-s")
|
||||
else:
|
||||
args.append("-e")
|
||||
return run("coffee", args=args, source=source)
|
||||
|
||||
|
||||
def cake(task, cwd):
|
||||
return run("cake", args=task, cwd=cwd)
|
||||
|
||||
|
||||
def isCoffee(view=None):
|
||||
if view is None:
|
||||
view = sublime.active_window().active_view()
|
||||
return 'source.coffee' in view.scope_name(0)
|
||||
|
||||
|
||||
class Text():
|
||||
@staticmethod
|
||||
def all(view):
|
||||
return view.substr(sublime.Region(0, view.size()))
|
||||
|
||||
@staticmethod
|
||||
def sel(view):
|
||||
text = []
|
||||
for region in view.sel():
|
||||
if region.empty():
|
||||
continue
|
||||
text.append(view.substr(region))
|
||||
return "".join(text)
|
||||
|
||||
@staticmethod
|
||||
def get(view):
|
||||
text = Text.sel(view)
|
||||
if len(text) > 0:
|
||||
return text
|
||||
return Text.all(view)
|
||||
|
||||
|
||||
class CompileCommand(TextCommand):
|
||||
def is_enabled(self):
|
||||
return isCoffee(self.view)
|
||||
|
||||
def run(self, *args, **kwargs):
|
||||
no_wrapper = settings.get('noWrapper', True)
|
||||
compile_dir = settings.get('compileDir')
|
||||
args = ['-c', self.view.file_name()]
|
||||
# print self.view.file_name()
|
||||
if no_wrapper:
|
||||
args = ['-b'] + args
|
||||
# print compile_dir
|
||||
# print isinstance(compile_dir, unicode)
|
||||
if compile_dir and isinstance(compile_dir, str) or isinstance(compile_dir, unicode):
|
||||
print "Compile dir specified: " + compile_dir
|
||||
if not os.path.exists(compile_dir):
|
||||
os.makedirs(compile_dir)
|
||||
print "Compile dir did not exist, created folder: " + compile_dir
|
||||
folder, file_nm = os.path.split(self.view.file_name())
|
||||
print folder
|
||||
args = ['--output', compile_dir] + args
|
||||
# print args
|
||||
# print args
|
||||
result = run("coffee", args=args)
|
||||
|
||||
if result['okay'] is True:
|
||||
status = 'Compilation Succeeded'
|
||||
else:
|
||||
status = 'Compilation Failed'
|
||||
|
||||
sublime.status_message(status)
|
||||
|
||||
|
||||
class CompileAndDisplayCommand(TextCommand):
|
||||
def is_enabled(self):
|
||||
return isCoffee(self.view)
|
||||
|
||||
def run(self, edit, **kwargs):
|
||||
output = self.view.window().new_file()
|
||||
output.set_scratch(True)
|
||||
opt = kwargs["opt"]
|
||||
if opt == '-p':
|
||||
output.set_syntax_file('Packages/JavaScript/JavaScript.tmLanguage')
|
||||
no_wrapper = settings.get('noWrapper', True)
|
||||
|
||||
args = [opt]
|
||||
print args
|
||||
if no_wrapper:
|
||||
args = ['-b'] + args
|
||||
|
||||
res = brew(args, Text.get(self.view))
|
||||
if res["okay"] is True:
|
||||
output.insert(edit, 0, res["out"])
|
||||
else:
|
||||
output.insert(edit, 0, res["err"].split("\n")[0])
|
||||
|
||||
|
||||
class CheckSyntaxCommand(TextCommand):
|
||||
def is_enabled(self):
|
||||
return isCoffee(self.view)
|
||||
|
||||
def run(self, edit):
|
||||
res = brew(['-b', '-p'], Text.get(self.view))
|
||||
if res["okay"] is True:
|
||||
status = 'Valid'
|
||||
else:
|
||||
status = res["err"].split("\n")[0]
|
||||
sublime.status_message('Syntax %s' % status)
|
||||
|
||||
|
||||
class RunScriptCommand(WindowCommand):
|
||||
def finish(self, text):
|
||||
if text == '':
|
||||
return
|
||||
text = "{puts, print} = require 'util'\n" + text
|
||||
res = brew(['-b'], text)
|
||||
if res["okay"] is True:
|
||||
output = self.window.new_file()
|
||||
output.set_scratch(True)
|
||||
edit = output.begin_edit()
|
||||
output.insert(edit, 0, res["out"])
|
||||
output.end_edit(edit)
|
||||
else:
|
||||
sublime.status_message('Syntax %s' % res["err"].split("\n")[0])
|
||||
|
||||
def run(self):
|
||||
sel = Text.sel(sublime.active_window().active_view())
|
||||
if len(sel) > 0:
|
||||
if not isCoffee():
|
||||
return
|
||||
self.finish(sel)
|
||||
else:
|
||||
self.window.show_input_panel('Coffee >', '', self.finish, None, None)
|
||||
|
||||
|
||||
class RunCakeTaskCommand(WindowCommand):
|
||||
def finish(self, task):
|
||||
if task == '':
|
||||
return
|
||||
|
||||
if not self.window.folders():
|
||||
cakepath = path.dirname(self.window.active_view().file_name())
|
||||
else:
|
||||
cakepath = path.join(self.window.folders()[0], 'Cakefile')
|
||||
if not path.exists(cakepath):
|
||||
cakepath = path.dirname(self.window.active_view().file_name())
|
||||
|
||||
if not path.exists(cakepath):
|
||||
return sublime.status_message("Cakefile not found.")
|
||||
|
||||
res = cake(task, cakepath)
|
||||
if res["okay"] is True:
|
||||
if "No such task" in res["out"]:
|
||||
msg = "doesn't exist"
|
||||
else:
|
||||
msg = "suceeded"
|
||||
else:
|
||||
msg = "failed"
|
||||
sublime.status_message("Task %s - %s." % (task, msg))
|
||||
|
||||
def run(self):
|
||||
self.window.show_input_panel('Cake >', '', self.finish, None, None)
|
||||
|
||||
|
||||
# _
|
||||
# __ _ _ __ ___ _ __ __ _(_)
|
||||
# / _` | '_ \ / _ \| '_ \\ \/ / |
|
||||
# | (_| | |_) | (_) | | | |> <| |
|
||||
# \__,_| .__/ \___/|_| |_/_/\_\_|
|
||||
# |_|
|
||||
|
||||
def watched_filename(view_id):
|
||||
view = ToggleWatch.views[view_id]['input_obj']
|
||||
if view.file_name() is not None:
|
||||
filename = view.file_name().split('/')[-1]
|
||||
else:
|
||||
filename = "Unsaved File"
|
||||
return filename
|
||||
|
||||
|
||||
class ToggleWatch(TextCommand):
|
||||
views = {}
|
||||
outputs = {}
|
||||
|
||||
def is_enabled(self):
|
||||
return isCoffee(self.view)
|
||||
|
||||
def run(self, edit):
|
||||
myvid = self.view.id()
|
||||
|
||||
if not myvid in ToggleWatch.views:
|
||||
|
||||
views = ToggleWatch.views
|
||||
views[myvid] = {'watched': True, 'modified': True, 'input_closed': False}
|
||||
views[myvid]["input_obj"] = self.view
|
||||
print "Now watching", watched_filename(myvid)
|
||||
createOut(myvid)
|
||||
|
||||
else:
|
||||
views = ToggleWatch.views
|
||||
|
||||
views[myvid]['watched'] = not views[myvid]['watched']
|
||||
if not views[myvid]['watched']:
|
||||
print "Stopped watching", watched_filename(myvid)
|
||||
|
||||
if views[myvid]['output_open'] is False:
|
||||
print "Openning output and watching", watched_filename(myvid)
|
||||
createOut(myvid)
|
||||
|
||||
elif views[myvid]['watched'] is True:
|
||||
print "Resuming watching", watched_filename(myvid)
|
||||
refreshOut(myvid)
|
||||
|
||||
|
||||
def cleanUp(input_view_id):
|
||||
del ToggleWatch.outputs[ToggleWatch.views[input_view_id]['output_id']]
|
||||
del ToggleWatch.views[input_view_id]
|
||||
return
|
||||
|
||||
|
||||
def get_output_filename(input_view_id):
|
||||
input_filename = watched_filename(input_view_id)
|
||||
fileName, fileExtension = os.path.splitext(input_filename)
|
||||
output_filename = fileName + '.js'
|
||||
return output_filename
|
||||
|
||||
|
||||
def createOut(input_view_id):
|
||||
#create output panel and save
|
||||
this_view = ToggleWatch.views[input_view_id]
|
||||
outputs = ToggleWatch.outputs
|
||||
#print this_view
|
||||
input_filename = watched_filename(input_view_id)
|
||||
print input_filename
|
||||
|
||||
output = this_view["input_obj"].window().new_file()
|
||||
output.set_scratch(True)
|
||||
output.set_syntax_file('Packages/JavaScript/JavaScript.tmLanguage')
|
||||
this_view['output_id'] = output.id()
|
||||
this_view["output_obj"] = output
|
||||
this_view["output_open"] = True
|
||||
# setting output filename
|
||||
# print output.settings().set('filename', '[Compiled]' + input_filename)
|
||||
# Getting file extension
|
||||
output_filename = get_output_filename(input_view_id)
|
||||
output.set_name(output_filename)
|
||||
|
||||
if not output.id() in outputs:
|
||||
outputs[output.id()] = {'boundto': input_view_id}
|
||||
refreshOut(input_view_id)
|
||||
return output
|
||||
|
||||
|
||||
def refreshOut(view_id):
|
||||
|
||||
this_view = ToggleWatch.views[view_id]
|
||||
this_view['last_modified'] = time.mktime(time.gmtime())
|
||||
#refresh the output view
|
||||
no_wrapper = settings.get('noWrapper', True)
|
||||
|
||||
args = ['-p']
|
||||
if no_wrapper:
|
||||
args = ['-b'] + args
|
||||
|
||||
res = brew(args, Text.get(this_view['input_obj']))
|
||||
output = this_view['output_obj']
|
||||
this_view['modified'] = False
|
||||
|
||||
if res["okay"] is True:
|
||||
edit = output.begin_edit()
|
||||
output.erase(edit, sublime.Region(0, output.size()))
|
||||
output.insert(edit, 0, res["out"])
|
||||
output.end_edit(edit)
|
||||
print "Refreshed"
|
||||
else:
|
||||
edit = output.begin_edit()
|
||||
output.erase(edit, sublime.Region(0, output.size()))
|
||||
output.insert(edit, 0, res["err"].split("\n")[0])
|
||||
output.end_edit(edit)
|
||||
return
|
||||
|
||||
|
||||
def isView(view_id):
|
||||
# are they modifying a view (rather than a panel, etc.)
|
||||
if not view_id:
|
||||
return False
|
||||
window = sublime.active_window()
|
||||
view = window.active_view() if window != None else None
|
||||
return (view is not None and view.id() == view_id)
|
||||
|
||||
|
||||
def close_output(input_id):
|
||||
views = ToggleWatch.views
|
||||
v = views[input_id]
|
||||
output = v['output_obj']
|
||||
# output_id = v['output_id']
|
||||
# print "close output"
|
||||
if v['output_open'] is True:
|
||||
#print "the output is open so we should attempt to close it"
|
||||
output.window().focus_view(output)
|
||||
output.window().run_command("close")
|
||||
print watched_filename(input_id), "was closed. Closing the Output"
|
||||
#v['output_open'] = False
|
||||
cleanUp(input_id)
|
||||
|
||||
return
|
||||
|
||||
|
||||
class CaptureEditing(sublime_plugin.EventListener):
|
||||
|
||||
def handleTimeout(self, vid):
|
||||
this_view = ToggleWatch.views[vid]
|
||||
modified = this_view['modified']
|
||||
if modified is True:
|
||||
# been 1000ms since the last modification
|
||||
#print "handling"
|
||||
refreshOut(vid)
|
||||
|
||||
def on_modified(self, view):
|
||||
vid = view.id()
|
||||
watch_modified = settings.get('watchOnModified')
|
||||
|
||||
if watch_modified is not False and vid in ToggleWatch.views:
|
||||
if watch_modified is True:
|
||||
delay = 0.5
|
||||
elif watch_modified < 0.5:
|
||||
delay = 0.5
|
||||
else:
|
||||
delay = watch_modified
|
||||
#then we have a watched input.
|
||||
this_view = ToggleWatch.views[vid]
|
||||
#print " this view is ", this_view
|
||||
if this_view['modified'] is False:
|
||||
this_view['modified'] = True
|
||||
#print " trigger "
|
||||
if this_view['watched'] is True:
|
||||
sublime.set_timeout(functools.partial(self.handleTimeout, vid), int(delay * 1000))
|
||||
return
|
||||
|
||||
def on_post_save(self, view):
|
||||
# print "isCoffee " + str(isCoffee())
|
||||
watch_save = settings.get('watchOnSave', True)
|
||||
if watch_save:
|
||||
save_id = view.id()
|
||||
views = ToggleWatch.views
|
||||
if save_id in views:
|
||||
# getting view object
|
||||
save_view = ToggleWatch.views[save_id]
|
||||
# check if modified
|
||||
if save_view['modified'] is True:
|
||||
refreshOut(save_id)
|
||||
compile_on_save = settings.get('compileOnSave', True)
|
||||
if compile_on_save is True and isCoffee() is True:
|
||||
print "Compiling on save..."
|
||||
view.run_command("compile")
|
||||
show_compile_output_on_save = settings.get('showOutputOnSave', True)
|
||||
if show_compile_output_on_save is True and isCoffee() is True and CompileOutput.IS_OPEN is True:
|
||||
print "Updating output panel..."
|
||||
view.run_command("compile_output")
|
||||
|
||||
return
|
||||
|
||||
def on_close(self, view):
|
||||
close_id = view.id()
|
||||
views = ToggleWatch.views
|
||||
if close_id in views:
|
||||
#this is an input
|
||||
#print "input was closed"
|
||||
views[close_id]['input_closed'] = True
|
||||
close_output(close_id)
|
||||
|
||||
if close_id in ToggleWatch.outputs and views[ToggleWatch.outputs[close_id]['boundto']]['input_closed'] is not True:
|
||||
#this is an output
|
||||
#print "an output was closed!"
|
||||
boundview = ToggleWatch.outputs[close_id]['boundto']
|
||||
thatview = views[boundview]
|
||||
thatview['output_open'] = False
|
||||
thatview['watched'] = False
|
||||
|
||||
filename = watched_filename(boundview)
|
||||
print "The output was closed. No longer watching", filename
|
||||
|
||||
return
|
||||
|
||||
|
||||
class CompileOutput(TextCommand):
|
||||
PANEL_NAME = 'coffee_compile_output'
|
||||
IS_OPEN = False
|
||||
|
||||
def is_enabled(self):
|
||||
return isCoffee(self.view)
|
||||
|
||||
def run(self, edit):
|
||||
window = self.view.window()
|
||||
|
||||
#refresh the output view
|
||||
no_wrapper = settings.get('noWrapper', True)
|
||||
|
||||
# args = ['-p']
|
||||
if no_wrapper:
|
||||
args = ['-b']
|
||||
|
||||
res = brew(args, Text.get(self.view))
|
||||
panel = window.get_output_panel(self.PANEL_NAME)
|
||||
panel.set_syntax_file('Packages/JavaScript/JavaScript.tmLanguage')
|
||||
panel.set_read_only(False)
|
||||
output = panel
|
||||
# print res["err"]
|
||||
|
||||
if res["okay"] is True:
|
||||
edit = output.begin_edit()
|
||||
output.erase(edit, sublime.Region(0, output.size()))
|
||||
output.insert(edit, 0, res["out"])
|
||||
output.end_edit(edit)
|
||||
# print "Refreshed"
|
||||
else:
|
||||
edit = output.begin_edit()
|
||||
output.erase(edit, sublime.Region(0, output.size()))
|
||||
output.insert(edit, 0, res["err"])
|
||||
output.end_edit(edit)
|
||||
output.sel().clear()
|
||||
output.set_read_only(True)
|
||||
|
||||
window.run_command('show_panel', {'panel': 'output.%s' % self.PANEL_NAME})
|
||||
self.IS_OPEN = True
|
||||
return
|
||||
Reference in New Issue
Block a user