Last active
August 29, 2015 14:01
-
-
Save derjanb/544c8136ea18491656f3 to your computer and use it in GitHub Desktop.
Sublime Text 3 Plugin to jump from the search context and diff files directly to the 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
import sublime | |
import sublime_plugin | |
import re | |
import os | |
# Sublime Text 3 Plugin to jump from the search context and diff files directly to the file | |
# | |
# Version 1.1 | |
# | |
# Taken from skuroda (http://stackoverflow.com/questions/16767732/sublime-text-how-to-jump-to-file-from-find-results-using-keyboard) and extended by derjanb | |
# | |
# Sample User Key Bindings: | |
# | |
# { "keys": ["enter"], "command": "find_in_files_goto", | |
# "context": [{ | |
# "key": "selector", | |
# "operator": "equal", | |
# "operand": "text.find-in-files" | |
# }] | |
# }, | |
# { "keys": ["enter"], "command": "find_in_files_goto", | |
# "context": [{ | |
# "key": "selector", | |
# "operator": "equal", | |
# "operand": "source.diff" | |
# }] | |
# } | |
class FindInFilesGotoCommand(sublime_plugin.TextCommand): | |
def run(self, edit): | |
view = self.view | |
if view.name() == "Find Results": | |
line_no = self.get_line_no() | |
file_name = self.get_file() | |
if line_no is not None and file_name is not None: | |
file_loc = "%s:%s" % (file_name, line_no) | |
view.window().open_file(file_loc, sublime.ENCODED_POSITION) | |
elif file_name is not None: | |
view.window().open_file(file_name) | |
else: | |
# if view.name().find("EasyDiff") == 0: | |
(self.section, self.patched_file) = self.determine_diff_type() | |
line_no = self.get_diff_line_no() | |
file_name = self.get_diff_file() | |
if line_no is not None and file_name is not None: | |
file_loc = "%s:%s" % (file_name, line_no) | |
view.window().open_file(file_loc, sublime.ENCODED_POSITION) | |
elif file_name is not None: | |
view.window().open_file(file_name) | |
def determine_diff_type(self): | |
view = self.view | |
line = view.line(view.text_point(0, 0)) | |
line_text = view.substr(line) | |
if (line_text.find("Index: ") == 0): | |
return r"^@@ [-\+]+(\d*),(\d*) [-\+]+(\d*),(\d*) @@$", r"\+\+\+ ([^\(]*).*" | |
elif (line_text.find("diff --git ") == 0): | |
return r"^@@ [-\+]+(\d*),(\d*) [-\+]+(\d*),(\d*) @@ .*", r"\+\+\+ (?:/b)?([^\(]*).*" | |
else: | |
print("Warning: unknown diff format!") | |
return None, None, None | |
def get_diff_line_no(self): | |
view = self.view | |
if len(view.sel()) == 1: | |
line = view.line(view.sel()[0]) | |
r = 0 | |
a = 0 | |
c = 0 | |
d = None | |
while line.begin() > 0: | |
line_text = view.substr(line) | |
match = re.match(self.patched_file, line_text) | |
if match: | |
break | |
match = re.match(self.section, line_text) | |
if match: | |
c = c | |
elif line_text[0] == "-": | |
r = r + 1 | |
elif line_text[0] == "+": | |
a = a + 1 | |
elif not d: | |
c = c + 1 | |
if not d: | |
if match: | |
d = int(match.group(1)) | |
if (r > 1): | |
c = c - r | |
if (a > 1): | |
c = c + a - 1 | |
a = 0 | |
r = 0 | |
print(line_text, d, c) | |
line = view.line(line.begin() - 1) | |
o = None | |
if d: | |
o = d + (a - r) + c | |
print(o, d, a, r, c) | |
return o | |
def get_diff_file(self): | |
view = self.view | |
if len(view.sel()) == 1: | |
line = view.line(view.sel()[0]) | |
while line.begin() > 0: | |
line_text = view.substr(line) | |
match = re.match(self.patched_file, line_text) | |
if match: | |
name = match.group(1).strip() | |
print(name) | |
if os.path.exists(name): | |
return name | |
if view.file_name(): | |
global_folder, filename = os.path.split(view.file_name()) | |
aname = os.path.join(global_folder, name) | |
print(aname) | |
if os.path.exists(aname): | |
return aname | |
line = view.line(line.begin() - 1) | |
return None | |
def get_line_no(self): | |
view = self.view | |
if len(view.sel()) == 1: | |
line_text = view.substr(view.line(view.sel()[0])) | |
match = re.match(r"\s*(\d+).+", line_text) | |
if match: | |
return match.group(1) | |
return None | |
def get_file(self): | |
view = self.view | |
if len(view.sel()) == 1: | |
line = view.line(view.sel()[0]) | |
while line.begin() > 0: | |
line_text = view.substr(line) | |
match = re.match(r"(.+):$", line_text) | |
if match: | |
if os.path.exists(match.group(1)): | |
return match.group(1) | |
line = view.line(line.begin() - 1) | |
return None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment