feat(SublimeText2.GitPackages): cache packages
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
import functools
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
import sublime
|
||||
import sublime_plugin
|
||||
from git import GitTextCommand, GitWindowCommand, plugin_file, view_contents, _make_text_safeish
|
||||
import add
|
||||
|
||||
history = []
|
||||
|
||||
|
||||
class GitQuickCommitCommand(GitTextCommand):
|
||||
def run(self, edit):
|
||||
self.get_window().show_input_panel("Message", "",
|
||||
self.on_input, None, None)
|
||||
|
||||
def on_input(self, message):
|
||||
if message.strip() == "":
|
||||
self.panel("No commit message provided")
|
||||
return
|
||||
self.run_command(['git', 'add', self.get_file_name()],
|
||||
functools.partial(self.add_done, message))
|
||||
|
||||
def add_done(self, message, result):
|
||||
if result.strip():
|
||||
sublime.error_message("Error adding file:\n" + result)
|
||||
return
|
||||
self.run_command(['git', 'commit', '-m', message])
|
||||
|
||||
|
||||
# Commit is complicated. It'd be easy if I just wanted to let it run
|
||||
# on OSX, and assume that subl was in the $PATH. However... I can't do
|
||||
# that. Second choice was to set $GIT_EDITOR to sublime text for the call
|
||||
# to commit, and let that Just Work. However, on Windows you can't pass
|
||||
# -w to sublime, which means the editor won't wait, and so the commit will fail
|
||||
# with an empty message.
|
||||
# Thus this flow:
|
||||
# 1. `status --porcelain --untracked-files=no` to know whether files need
|
||||
# to be committed
|
||||
# 2. `status` to get a template commit message (not the exact one git uses; I
|
||||
# can't see a way to ask it to output that, which is not quite ideal)
|
||||
# 3. Create a scratch buffer containing the template
|
||||
# 4. When this buffer is closed, get its contents with an event handler and
|
||||
# pass execution back to the original command. (I feel that the way this
|
||||
# is done is a total hack. Unfortunately, I cannot see a better way right
|
||||
# now.)
|
||||
# 5. Strip lines beginning with # from the message, and save in a temporary
|
||||
# file
|
||||
# 6. `commit -F [tempfile]`
|
||||
class GitCommitCommand(GitWindowCommand):
|
||||
active_message = False
|
||||
extra_options = ""
|
||||
|
||||
def run(self):
|
||||
self.lines = []
|
||||
self.working_dir = self.get_working_dir()
|
||||
self.run_command(
|
||||
['git', 'status', '--untracked-files=no', '--porcelain'],
|
||||
self.porcelain_status_done
|
||||
)
|
||||
|
||||
def porcelain_status_done(self, result):
|
||||
# todo: split out these status-parsing things... asdf
|
||||
has_staged_files = False
|
||||
result_lines = result.rstrip().split('\n')
|
||||
for line in result_lines:
|
||||
if line and not line[0].isspace():
|
||||
has_staged_files = True
|
||||
break
|
||||
if not has_staged_files:
|
||||
self.panel("Nothing to commit")
|
||||
return
|
||||
# Okay, get the template!
|
||||
s = sublime.load_settings("Git.sublime-settings")
|
||||
if s.get("verbose_commits"):
|
||||
self.run_command(['git', 'diff', '--staged', '--no-color'], self.diff_done)
|
||||
else:
|
||||
self.run_command(['git', 'status'], self.diff_done)
|
||||
|
||||
def diff_done(self, result):
|
||||
settings = sublime.load_settings("Git.sublime-settings")
|
||||
historySize = settings.get('history_size')
|
||||
|
||||
def format(line):
|
||||
return '# ' + line.replace("\n", " ")
|
||||
|
||||
if not len(self.lines):
|
||||
self.lines = ["", ""]
|
||||
|
||||
self.lines.extend(map(format, history[:historySize]))
|
||||
self.lines.extend([
|
||||
"# --------------",
|
||||
"# Please enter the commit message for your changes. Everything below",
|
||||
"# this paragraph is ignored, and an empty message aborts the commit.",
|
||||
"# Just close the window to accept your message.",
|
||||
result.strip()
|
||||
])
|
||||
template = "\n".join(self.lines)
|
||||
msg = self.window.new_file()
|
||||
msg.set_scratch(True)
|
||||
msg.set_name("COMMIT_EDITMSG")
|
||||
self._output_to_view(msg, template, syntax=plugin_file("syntax/Git Commit Message.tmLanguage"))
|
||||
msg.sel().clear()
|
||||
msg.sel().add(sublime.Region(0, 0))
|
||||
GitCommitCommand.active_message = self
|
||||
|
||||
def message_done(self, message):
|
||||
# filter out the comments (git commit doesn't do this automatically)
|
||||
settings = sublime.load_settings("Git.sublime-settings")
|
||||
historySize = settings.get('history_size')
|
||||
lines = [line for line in message.split("\n# --------------")[0].split("\n")
|
||||
if not line.lstrip().startswith('#')]
|
||||
message = '\n'.join(lines).strip()
|
||||
|
||||
if len(message) and historySize:
|
||||
history.insert(0, message)
|
||||
# write the temp file
|
||||
message_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
message_file.write(_make_text_safeish(message, self.fallback_encoding, 'encode'))
|
||||
message_file.close()
|
||||
self.message_file = message_file
|
||||
# and actually commit
|
||||
with open(message_file.name, 'r') as fp:
|
||||
self.run_command(['git', 'commit', '-F', '-', self.extra_options],
|
||||
self.commit_done, working_dir=self.working_dir, stdin=fp.read())
|
||||
|
||||
def commit_done(self, result, **kwargs):
|
||||
os.remove(self.message_file.name)
|
||||
self.panel(result)
|
||||
|
||||
|
||||
class GitCommitAmendCommand(GitCommitCommand):
|
||||
extra_options = "--amend"
|
||||
|
||||
def diff_done(self, result):
|
||||
self.after_show = result
|
||||
self.run_command(['git', 'log', '-n', '1', '--format=format:%B'], self.amend_diff_done)
|
||||
|
||||
def amend_diff_done(self, result):
|
||||
self.lines = result.split("\n")
|
||||
super(GitCommitAmendCommand, self).diff_done(self.after_show)
|
||||
|
||||
|
||||
class GitCommitMessageListener(sublime_plugin.EventListener):
|
||||
def on_close(self, view):
|
||||
if view.name() != "COMMIT_EDITMSG":
|
||||
return
|
||||
command = GitCommitCommand.active_message
|
||||
if not command:
|
||||
return
|
||||
message = view_contents(view)
|
||||
command.message_done(message)
|
||||
|
||||
|
||||
class GitCommitHistoryCommand(sublime_plugin.TextCommand):
|
||||
def run(self, edit):
|
||||
self.edit = edit
|
||||
self.view.window().show_quick_panel(history, self.panel_done, sublime.MONOSPACE_FONT)
|
||||
|
||||
def panel_done(self, index):
|
||||
if index > -1:
|
||||
self.view.replace(self.edit, self.view.sel()[0], history[index] + '\n')
|
||||
|
||||
|
||||
class GitCommitSelectedHunk(add.GitAddSelectedHunkCommand):
|
||||
def run(self, edit):
|
||||
self.run_command(['git', 'diff', '--no-color', self.get_file_name()], self.cull_diff)
|
||||
self.get_window().run_command('git_commit')
|
Reference in New Issue
Block a user